* Makefile: integrate Mono.Mozilla wrapper in the build.
[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 bool AddField (FieldBase field)
584                 {
585                         if (!AddMember (field))
586                                 return false;
587
588                         if (fields == null)
589                                 fields = new MemberCoreArrayList ();
590
591                         fields.Add (field);
592
593                         if ((field.ModFlags & Modifiers.STATIC) != 0)
594                                 return true;
595
596                         if (first_nonstatic_field == null) {
597                                 first_nonstatic_field = field;
598                                 return true;
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                         return true;
608                 }
609
610                 public void AddProperty (Property prop)
611                 {
612                         if (!AddMember (prop) || 
613                                 !AddMember (prop.Get) || !AddMember (prop.Set))
614                                 return;
615
616                         if (properties == null)
617                                 properties = new MemberCoreArrayList ();
618
619                         if (prop.MemberName.Left != null)
620                                 AddMemberToList (prop, properties, true);
621                         else 
622                                 AddMemberToList (prop, properties, false);
623                 }
624
625                 public void AddEvent (Event e)
626                 {
627                         if (!AddMember (e))
628                                 return;
629
630                         if (e is EventProperty) {
631                                 if (!AddMember (e.Add))
632                                         return;
633
634                                 if (!AddMember (e.Remove))
635                                         return;
636                         }
637
638                         if (events == null)
639                                 events = new MemberCoreArrayList ();
640
641                         events.Add (e);
642                 }
643
644                 /// <summary>
645                 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
646                 /// </summary>
647                 public void AddIndexer (Indexer i)
648                 {
649                         if (indexers == null)
650                                 indexers = new ArrayList ();
651
652                         if (i.IsExplicitImpl)
653                                 AddMemberToList (i, indexers, true);
654                         else 
655                                 AddMemberToList (i, indexers, false);
656                 }
657
658                 public void AddOperator (Operator op)
659                 {
660                         if (!AddMember (op))
661                                 return;
662
663                         if (operators == null)
664                                 operators = new OperatorArrayList (this);
665
666                         operators.Add (op);
667                 }
668
669                 public void AddCompilerGeneratedClass (CompilerGeneratedClass c)
670                 {
671                         Report.Debug (64, "ADD COMPILER GENERATED CLASS", this, c);
672
673                         if (compiler_generated == null)
674                                 compiler_generated = new ArrayList ();
675
676                         compiler_generated.Add (c);
677                 }
678
679                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
680                 {
681                         if (a.Type == TypeManager.default_member_type) {
682                                 if (Indexers != null) {
683                                         Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
684                                         return;
685                                 }
686                         }
687                         
688                         base.ApplyAttributeBuilder (a, cb);
689                 } 
690
691                 public override AttributeTargets AttributeTargets {
692                         get {
693                                 throw new NotSupportedException ();
694                         }
695                 }
696
697                 public ArrayList Types {
698                         get {
699                                 return types;
700                         }
701                 }
702
703                 public MemberCoreArrayList Methods {
704                         get {
705                                 return methods;
706                         }
707                 }
708
709                 public ArrayList Constants {
710                         get {
711                                 return constants;
712                         }
713                 }
714
715                 public ArrayList CompilerGenerated {
716                         get {
717                                 return compiler_generated;
718                         }
719                 }
720
721                 protected Type BaseType {
722                         get {
723                                 return TypeBuilder.BaseType;
724                         }
725                 }
726                 
727                 public ArrayList Bases {
728                         get {
729                                 return type_bases;
730                         }
731
732                         set {
733                                 type_bases = value;
734                         }
735                 }
736
737                 public ArrayList Fields {
738                         get {
739                                 return fields;
740                         }
741                 }
742
743                 public ArrayList InstanceConstructors {
744                         get {
745                                 return instance_constructors;
746                         }
747                 }
748
749                 public ArrayList Properties {
750                         get {
751                                 return properties;
752                         }
753                 }
754
755                 public ArrayList Events {
756                         get {
757                                 return events;
758                         }
759                 }
760                 
761                 public ArrayList Indexers {
762                         get {
763                                 return indexers;
764                         }
765                 }
766
767                 public ArrayList Operators {
768                         get {
769                                 return operators;
770                         }
771                 }
772
773                 public ArrayList Delegates {
774                         get {
775                                 return delegates;
776                         }
777                 }
778                 
779                 protected override TypeAttributes TypeAttr {
780                         get {
781                                 return Modifiers.TypeAttr (ModFlags, IsTopLevel) | base.TypeAttr;
782                         }
783                 }
784
785                 public string IndexerName {
786                         get {
787                                 return indexers == null ? DefaultIndexerName : indexer_name;
788                         }
789                 }
790
791                 public bool IsComImport {
792                         get {
793                                 if (OptAttributes == null)
794                                         return false;
795
796                                 return OptAttributes.Contains (TypeManager.comimport_attr_type);
797                         }
798                 }
799
800                 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
801                 {
802                         if ((field.ModFlags & Modifiers.STATIC) != 0){
803                                 if (initialized_static_fields == null)
804                                         initialized_static_fields = new ArrayList (4);
805
806                                 initialized_static_fields.Add (expression);
807                         } else {
808                                 if (initialized_fields == null)
809                                         initialized_fields = new ArrayList (4);
810
811                                 initialized_fields.Add (expression);
812                         }
813                 }
814
815                 //
816                 // Emits the instance field initializers
817                 //
818                 public bool EmitFieldInitializers (EmitContext ec)
819                 {
820                         ArrayList fields;
821                         
822                         if (ec.IsStatic){
823                                 fields = initialized_static_fields;
824                         } else {
825                                 fields = initialized_fields;
826                         }
827
828                         if (fields == null)
829                                 return true;
830
831                         foreach (FieldInitializer f in fields) {
832                                 f.EmitStatement (ec);
833                         }
834                         return true;
835                 }
836                 
837                 public override string DocComment {
838                         get {
839                                 return comment;
840                         }
841                         set {
842                                 if (value == null)
843                                         return;
844
845                                 comment += value;
846                         }
847                 }
848
849                 public PendingImplementation PendingImplementations {
850                         get { return pending; }
851                 }
852
853                 public override bool GetClsCompliantAttributeValue ()
854                 {
855                         if (PartialContainer != this)
856                                 return PartialContainer.GetClsCompliantAttributeValue ();
857
858                         return base.GetClsCompliantAttributeValue ();
859                 }
860
861                 public virtual void AddBasesForPart (DeclSpace part, ArrayList bases)
862                 {
863                         // FIXME: get rid of partial_parts and store lists of bases of each part here
864                         // assumed, not verified: 'part' is in 'partial_parts' 
865                         ((TypeContainer) part).Bases = bases;
866                 }
867
868                 TypeExpr[] GetNormalBases (out TypeExpr base_class)
869                 {
870                         base_class = null;
871                         if (Bases == null)
872                                 return null;
873
874                         int count = Bases.Count;
875                         int start = 0, i, j;
876
877                         if (Kind == Kind.Class){
878                                 TypeExpr name = ((Expression) Bases [0]).ResolveAsBaseTerminal (this, false);
879
880                                 if (name == null){
881                                         return null;
882                                 }
883
884                                 if (!name.IsInterface) {
885                                         // base_class could be a class, struct, enum, delegate.
886                                         // This is validated in GetClassBases.
887                                         base_class = name;
888                                         start = 1;
889                                 }
890                         }
891
892                         TypeExpr [] ifaces = new TypeExpr [count-start];
893                         
894                         for (i = start, j = 0; i < count; i++, j++){
895                                 TypeExpr resolved = ((Expression) Bases [i]).ResolveAsBaseTerminal (this, false);
896                                 if (resolved == null) {
897                                         return null;
898                                 }
899                                 
900                                 ifaces [j] = resolved;
901                         }
902
903                         return ifaces.Length == 0 ? null : ifaces;
904                 }
905
906
907                 TypeExpr[] GetNormalPartialBases (ref TypeExpr base_class)
908                 {
909                         ArrayList ifaces = new ArrayList (0);
910                         if (iface_exprs != null)
911                                 ifaces.AddRange (iface_exprs);
912
913                         foreach (TypeContainer part in partial_parts) {
914                                 TypeExpr new_base_class;
915                                 TypeExpr[] new_ifaces = part.GetClassBases (out new_base_class);
916                                 if (new_base_class != TypeManager.system_object_expr) {
917                                         if (base_class == TypeManager.system_object_expr)
918                                                 base_class = new_base_class;
919                                         else {
920                                                 if (new_base_class != null && !new_base_class.Equals (base_class)) {
921                                                         Report.SymbolRelatedToPreviousError (base_class.Location, "");
922                                                         Report.Error (263, part.Location,
923                                                                 "Partial declarations of `{0}' must not specify different base classes",
924                                                                 part.GetSignatureForError ());
925
926                                                         return null;
927                                                 }
928                                         }
929                                 }
930
931                                 if (new_ifaces == null)
932                                         continue;
933
934                                 foreach (TypeExpr iface in new_ifaces) {
935                                         if (ifaces.Contains (iface))
936                                                 continue;
937
938                                         ifaces.Add (iface);
939                                 }
940                         }
941
942                         if (ifaces.Count == 0)
943                                 return null;
944
945                         return (TypeExpr[])ifaces.ToArray (typeof (TypeExpr));
946                 }
947
948                 /// <summary>
949                 ///   This function computes the Base class and also the
950                 ///   list of interfaces that the class or struct @c implements.
951                 ///   
952                 ///   The return value is an array (might be null) of
953                 ///   interfaces implemented (as Types).
954                 ///   
955                 ///   The @base_class argument is set to the base object or null
956                 ///   if this is `System.Object'. 
957                 /// </summary>
958                 public virtual TypeExpr [] GetClassBases (out TypeExpr base_class)
959                 {
960                         TypeExpr[] ifaces = GetNormalBases (out base_class);
961
962                         if (ifaces == null)
963                                 return null;
964
965                         int count = ifaces.Length;
966
967                         for (int i = 0; i < count; i++) {
968                                 TypeExpr iface = (TypeExpr) ifaces [i];
969
970                                 if (!iface.IsInterface) {
971                                         if (Kind != Kind.Class) {
972                                                 // TODO: location of symbol related ....
973                                                 Error_TypeInListIsNotInterface (Location, iface.GetSignatureForError ());
974                                         }
975                                         else if (base_class != null)
976                                                 Report.Error (1721, Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
977                                                         GetSignatureForError (), base_class.GetSignatureForError (), iface.GetSignatureForError ());
978                                         else {
979                                                 Report.Error (1722, Location, "`{0}': Base class `{1}' must be specified as first",
980                                                         GetSignatureForError (), iface.GetSignatureForError ());
981                                         }
982                                         return null;
983                                 }
984
985                                 for (int x = 0; x < i; x++) {
986                                         if (iface.Equals (ifaces [x])) {
987                                                 Report.Error (528, Location,
988                                                               "`{0}' is already listed in " +
989                                                               "interface list", iface.GetSignatureForError ());
990                                                 return null;
991                                         }
992                                 }
993
994                                 if ((Kind == Kind.Interface) &&
995                                     !iface.AsAccessible (Parent, ModFlags)) {
996                                         Report.Error (61, Location,
997                                                       "Inconsistent accessibility: base " +
998                                                       "interface `{0}' is less accessible " +
999                                                       "than interface `{1}'", iface.Name,
1000                                                       Name);
1001                                         return null;
1002                                 }
1003                         }
1004                         return ifaces;
1005                 }
1006
1007                 bool CheckGenericInterfaces (Type[] ifaces)
1008                 {
1009 #if GMCS_SOURCE
1010                         ArrayList already_checked = new ArrayList ();
1011
1012                         for (int i = 0; i < ifaces.Length; i++) {
1013                                 Type iface = ifaces [i];
1014                                 foreach (Type t in already_checked) {
1015                                         if (iface == t)
1016                                                 continue;
1017
1018                                         Type[] inferred = new Type [CountTypeParameters];
1019                                         if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, inferred, null))
1020                                                 continue;
1021
1022                                         Report.Error (695, Location,
1023                                                 "`{0}' cannot implement both `{1}' and `{2}' " +
1024                                                 "because they may unify for some type parameter substitutions",
1025                                                 TypeManager.CSharpName (TypeBuilder), TypeManager.CSharpName (iface),
1026                                                 TypeManager.CSharpName (t));
1027                                         return false;
1028                                 }
1029
1030                                 already_checked.Add (iface);
1031                         }
1032 #endif
1033
1034                         return true;
1035                 }
1036
1037                 bool error = false;
1038                 
1039                 protected void Error_TypeInListIsNotInterface (Location loc, string type)
1040                 {
1041                         Report.Error (527, loc, "Type `{0}' in interface list is not an interface", type);
1042                 }
1043
1044                 bool CreateTypeBuilder ()
1045                 {
1046                         try {
1047                                 Type default_parent = null;
1048                                 if (Kind == Kind.Struct)
1049                                         default_parent = TypeManager.value_type;
1050                                 else if (Kind == Kind.Enum)
1051                                         default_parent = TypeManager.enum_type;
1052
1053                                 if (IsTopLevel){
1054                                         if (TypeManager.NamespaceClash (Name, Location)) {
1055                                                 return false;
1056                                         }
1057
1058                                         ModuleBuilder builder = CodeGen.Module.Builder;
1059                                         TypeBuilder = builder.DefineType (
1060                                                 Name, TypeAttr, default_parent, null);
1061                                 } else {
1062                                         TypeBuilder builder = Parent.TypeBuilder;
1063
1064                                         TypeBuilder = builder.DefineNestedType (
1065                                                 Basename, TypeAttr, default_parent, null);
1066                                 }
1067                         } catch (ArgumentException) {
1068                                 Report.RuntimeMissingSupport (Location, "static classes");
1069                                 return false;
1070                         }
1071
1072                         TypeManager.AddUserType (this);
1073
1074 #if GMCS_SOURCE
1075                         if (IsGeneric) {
1076                                 string[] param_names = new string [TypeParameters.Length];
1077                                 for (int i = 0; i < TypeParameters.Length; i++)
1078                                         param_names [i] = TypeParameters [i].Name;
1079
1080                                 gen_params = TypeBuilder.DefineGenericParameters (param_names);
1081
1082                                 int offset = CountTypeParameters - CurrentTypeParameters.Length;
1083                                 for (int i = offset; i < gen_params.Length; i++)
1084                                         CurrentTypeParameters [i - offset].Define (gen_params [i]);
1085                         }
1086 #endif
1087
1088                         return true;
1089                 }
1090
1091                 bool DefineBaseTypes ()
1092                 {
1093                         iface_exprs = GetClassBases (out base_type);
1094                         if (partial_parts != null) {
1095                                 iface_exprs = GetNormalPartialBases (ref base_type);
1096                         }
1097
1098                         //
1099                         // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1100                         // which in turn should have called DefineType()s on base types if necessary.
1101                         //
1102                         // None of the code below should trigger DefineType()s on classes that we depend on.
1103                         // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1104                         //
1105                         // Let's do it as soon as possible, since code below can call DefineType() on classes
1106                         // that depend on us to be populated before they are.
1107                         //
1108                         if (!(this is CompilerGeneratedClass))
1109                                 RootContext.RegisterOrder (this); 
1110
1111                         if (IsGeneric && base_type != null && TypeManager.IsAttributeType (base_type.Type)) {
1112                                 Report.Error (698, base_type.Location,
1113                                               "A generic type cannot derive from `{0}' because it is an attribute class",
1114                                               base_type.Name);
1115                                 return false;
1116                         }
1117
1118                         if (!CheckRecursiveDefinition (this))
1119                                 return false;
1120
1121                         if (base_type != null && base_type.Type != null) {
1122                                 TypeBuilder.SetParent (base_type.Type);
1123
1124                                 ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (base_type.Type);
1125                                 if (obsolete_attr != null && !IsInObsoleteScope)
1126                                         AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location);
1127                         }
1128
1129                         // add interfaces that were not added at type creation
1130                         if (iface_exprs != null) {
1131                                 ifaces = TypeManager.ExpandInterfaces (iface_exprs);
1132                                 if (ifaces == null)
1133                                         return false;
1134
1135                                 foreach (Type itype in ifaces)
1136                                         TypeBuilder.AddInterfaceImplementation (itype);
1137
1138                                 foreach (TypeExpr ie in iface_exprs) {
1139                                         ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (ie.Type);
1140                                         if ((oa != null) && !IsInObsoleteScope)
1141                                                 AttributeTester.Report_ObsoleteMessage (
1142                                                         oa, ie.GetSignatureForError (), Location);
1143                                 }
1144
1145                                 if (!CheckGenericInterfaces (ifaces))
1146                                         return false;
1147
1148                                 TypeManager.RegisterBuilder (TypeBuilder, ifaces);
1149                         }
1150
1151                         return true;
1152                 }
1153
1154                 //
1155                 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1156                 //
1157                 public TypeBuilder CreateType ()
1158                 {
1159                         if (TypeBuilder != null)
1160                                 return TypeBuilder;
1161
1162                         if (error)
1163                                 return null;
1164
1165                         if (!CreateTypeBuilder ()) {
1166                                 error = true;
1167                                 return null;
1168                         }
1169
1170                         if (partial_parts != null) {
1171                                 foreach (TypeContainer part in partial_parts)
1172                                         part.TypeBuilder = TypeBuilder;
1173                         }
1174
1175                         if (Types != null) {
1176                                 foreach (TypeContainer tc in Types) {
1177                                         if (tc.CreateType () == null) {
1178                                                 error = true;
1179                                                 return null;
1180                                         }
1181                                 }
1182                         }
1183
1184                         return TypeBuilder;
1185                 }
1186
1187                 bool type_defined;
1188
1189                 public override TypeBuilder DefineType ()
1190                 {
1191                         if (error)
1192                                 return null;
1193                         if (type_defined)
1194                                 return TypeBuilder;
1195
1196                         type_defined = true;
1197
1198                         if (CreateType () == null) {
1199                                 error = true;
1200                                 return null;
1201                         }
1202
1203                         if (!DefineBaseTypes ()) {
1204                                 error = true;
1205                                 return null;
1206                         }
1207
1208                         if (!(this is CompilerGeneratedClass)) {
1209                                 if (!ResolveMembers ()) {
1210                                         error = true;
1211                                         return null;
1212                                 }
1213                         }
1214
1215                         if (!DefineNestedTypes ()) {
1216                                 error = true;
1217                                 return null;
1218                         }
1219
1220                         return TypeBuilder;
1221                 }
1222
1223                 public bool ResolveMembers ()
1224                 {
1225                         if (members_resolved)
1226                                 return members_resolved_ok;
1227
1228                         members_resolved_ok = DoResolveMembers ();
1229                         members_resolved = true;
1230
1231                         return members_resolved_ok;
1232                 }
1233
1234                 protected virtual bool DoResolveMembers ()
1235                 {
1236                         if (methods != null) {
1237                                 foreach (Method method in methods) {
1238                                         if (!method.ResolveMembers ())
1239                                                 return false;
1240                                 }
1241                         }
1242
1243                         if (instance_constructors != null) {
1244                                 foreach (Constructor c in instance_constructors) {
1245                                         if (!c.ResolveMembers ())
1246                                                 return false;
1247                                 }
1248                         }
1249
1250                         if (default_static_constructor != null) {
1251                                 if (!default_static_constructor.ResolveMembers ())
1252                                         return false;
1253                         }
1254
1255                         if (operators != null) {
1256                                 foreach (Operator o in operators) {
1257                                         if (!o.ResolveMembers ())
1258                                                 return false;
1259                                 }
1260                         }
1261
1262                         if (properties != null) {
1263                                 foreach (PropertyBase p in properties) {
1264                                         if (!p.Get.IsDummy && !p.Get.ResolveMembers ())
1265                                                 return false;
1266                                         if (!p.Set.IsDummy && !p.Set.ResolveMembers ())
1267                                                 return false;
1268                                 }
1269                         }
1270
1271                         if (indexers != null) {
1272                                 foreach (PropertyBase p in indexers) {
1273                                         if (!p.Get.IsDummy && !p.Get.ResolveMembers ())
1274                                                 return false;
1275                                         if (!p.Set.IsDummy && !p.Set.ResolveMembers ())
1276                                                 return false;
1277                                 }
1278                         }
1279
1280                         if (events != null) {
1281                                 foreach (Event e in events) {
1282                                         if (!e.Add.ResolveMembers ())
1283                                                 return false;
1284                                         if (!e.Remove.ResolveMembers ())
1285                                                 return false;
1286                                 }
1287                         }
1288
1289                         if (compiler_generated != null) {
1290                                 foreach (CompilerGeneratedClass c in compiler_generated) {
1291                                         if (c.DefineType () == null)
1292                                                 return false;
1293                                 }
1294                         }
1295
1296                         return true;
1297                 }
1298
1299                 Constraints [] constraints;
1300                 public override void SetParameterInfo (ArrayList constraints_list)
1301                 {
1302                         if (PartialContainer == this) {
1303                                 base.SetParameterInfo (constraints_list);
1304                                 return;
1305                         }
1306
1307                         if (constraints_list == null)
1308                                 return;
1309
1310                         constraints = new Constraints [PartialContainer.CountCurrentTypeParameters];
1311
1312                         TypeParameter[] current_params = PartialContainer.CurrentTypeParameters;
1313                         for (int i = 0; i < constraints.Length; i++) {
1314                                 foreach (Constraints constraint in constraints_list) {
1315                                         if (constraint.TypeParameter == current_params [i].Name) {
1316                                                 constraints [i] = constraint;
1317                                                 break;
1318                                         }
1319                                 }
1320                         }
1321                 }
1322
1323                 bool UpdateTypeParameterConstraints ()
1324                 {
1325                         if (constraints == null)
1326                                 return true;
1327
1328                         TypeParameter[] current_params = PartialContainer.CurrentTypeParameters;
1329                         for (int i = 0; i < current_params.Length; i++) {
1330                                 if (!current_params [i].UpdateConstraints (this, constraints [i])) {
1331                                         Report.SymbolRelatedToPreviousError (Location, "");
1332                                         Report.Error (265, PartialContainer.Location,
1333                                                 "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
1334                                                 PartialContainer.GetSignatureForError (), current_params [i].Name);
1335                                         return false;
1336                                 }
1337                         }
1338
1339                         return true;
1340                 }
1341
1342                 public bool ResolveType ()
1343                 {
1344                         if (!DoResolveType ())
1345                                 return false;
1346
1347                         if (compiler_generated != null) {
1348                                 foreach (CompilerGeneratedClass c in compiler_generated)
1349                                         if (!c.ResolveType ())
1350                                                 return false;
1351                         }
1352
1353                         return true;
1354                 }
1355
1356                 protected virtual bool DoResolveType ()
1357                 {
1358                         if ((base_type != null) &&
1359                             (base_type.ResolveAsTypeTerminal (this, false) == null)) {
1360                                 error = true;
1361                                 return false;
1362                         }
1363
1364                         if (!IsGeneric)
1365                                 return true;
1366
1367                         if (PartialContainer != this)
1368                                 throw new InternalErrorException ();
1369
1370                         TypeExpr current_type = null;
1371
1372                         foreach (TypeParameter type_param in CurrentTypeParameters) {
1373                                 if (!type_param.Resolve (this)) {
1374                                         error = true;
1375                                         return false;
1376                                 }
1377                         }
1378
1379                         if (partial_parts != null) {
1380                                 foreach (TypeContainer part in partial_parts) {
1381                                         if (!part.UpdateTypeParameterConstraints ()) {
1382                                                 error = true;
1383                                                 return false;
1384                                         }
1385                                 }
1386                         }
1387
1388                         foreach (TypeParameter type_param in TypeParameters) {
1389                                 if (!type_param.DefineType (this)) {
1390                                         error = true;
1391                                         return false;
1392                                 }
1393                         }
1394
1395                         current_type = new ConstructedType (TypeBuilder, TypeParameters, Location);
1396
1397                         foreach (TypeParameter type_param in TypeParameters)
1398                                 if (!type_param.CheckDependencies ()) {
1399                                         error = true;
1400                                         return false;
1401                                 }
1402
1403                         if (current_type != null) {
1404                                 current_type = current_type.ResolveAsTypeTerminal (this, false);
1405                                 if (current_type == null) {
1406                                         error = true;
1407                                         return false;
1408                                 }
1409
1410                                 CurrentType = current_type.Type;
1411                         }
1412
1413                         return true;
1414                 }
1415
1416                 protected virtual bool DefineNestedTypes ()
1417                 {
1418                         if (Types != null) {
1419                                 foreach (TypeContainer tc in Types)
1420                                         if (tc.DefineType () == null)
1421                                                 return false;
1422                         }
1423
1424                         if (Delegates != null) {
1425                                 foreach (Delegate d in Delegates)
1426                                         if (d.DefineType () == null)
1427                                                 return false;
1428                         }
1429
1430                         return true;
1431                 }
1432
1433                 TypeContainer InTransit;
1434
1435                 protected bool CheckRecursiveDefinition (TypeContainer tc)
1436                 {
1437                         if (InTransit != null) {
1438                                 Report.SymbolRelatedToPreviousError (this);
1439                                 if (this is Interface)
1440                                         Report.Error (
1441                                                 529, tc.Location, "Inherited interface `{0}' causes a " +
1442                                                 "cycle in the interface hierarchy of `{1}'",
1443                                                 GetSignatureForError (), tc.GetSignatureForError ());
1444                                 else
1445                                         Report.Error (
1446                                                 146, tc.Location, "Circular base class dependency " +
1447                                                 "involving `{0}' and `{1}'",
1448                                                 tc.GetSignatureForError (), GetSignatureForError ());
1449                                 return false;
1450                         }
1451
1452                         InTransit = tc;
1453
1454                         if (base_type != null && base_type.Type != null) {
1455                                 Type t = TypeManager.DropGenericTypeArguments (base_type.Type);
1456                                 TypeContainer ptc = TypeManager.LookupTypeContainer (t);
1457                                 if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1458                                         return false;
1459                         }
1460
1461                         if (iface_exprs != null) {
1462                                 foreach (TypeExpr iface in iface_exprs) {
1463                                         Type itype = TypeManager.DropGenericTypeArguments (iface.Type);
1464                                         TypeContainer ptc = TypeManager.LookupTypeContainer (itype);
1465                                         if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1466                                                 return false;
1467                                 }
1468                         }
1469
1470                         if (!IsTopLevel && !Parent.PartialContainer.CheckRecursiveDefinition (this))
1471                                 return false;
1472
1473                         InTransit = null;
1474                         return true;
1475                 }
1476
1477                 public static void Error_KeywordNotAllowed (Location loc)
1478                 {
1479                         Report.Error (1530, loc, "Keyword `new' is not allowed on namespace elements");
1480                 }
1481
1482                 /// <summary>
1483                 ///   Populates our TypeBuilder with fields and methods
1484                 /// </summary>
1485                 public override bool DefineMembers ()
1486                 {
1487                         if (members_defined)
1488                                 return members_defined_ok;
1489
1490                         if (!base.DefineMembers ())
1491                                 return false;
1492
1493                         members_defined_ok = DoDefineMembers ();
1494                         members_defined = true;
1495
1496                         return members_defined_ok;
1497                 }
1498
1499                 protected virtual bool DoDefineMembers ()
1500                 {
1501                         if (iface_exprs != null) {
1502                                 foreach (TypeExpr iface in iface_exprs) {
1503                                         ConstructedType ct = iface as ConstructedType;
1504                                         if ((ct != null) && !ct.CheckConstraints (this))
1505                                                 return false;
1506                                 }
1507                         }
1508
1509                         if (base_type != null) {
1510                                 ConstructedType ct = base_type as ConstructedType;
1511                                 if ((ct != null) && !ct.CheckConstraints (this))
1512                                         return false;
1513                         }
1514
1515                         if (!IsTopLevel) {
1516                                 MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Basename, false);
1517                                 if (conflict_symbol == null) {
1518                                         if ((ModFlags & Modifiers.NEW) != 0)
1519                                                 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1520                                 } else {
1521                                         if ((ModFlags & Modifiers.NEW) == 0) {
1522                                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
1523                                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1524                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
1525                                         }
1526                                 }
1527                         }
1528
1529                         DefineContainerMembers (constants);
1530                         DefineContainerMembers (fields);
1531
1532                         if (Kind == Kind.Struct || Kind == Kind.Class) {
1533                                 pending = PendingImplementation.GetPendingImplementations (this);
1534                         }
1535                 
1536                         //
1537                         // Constructors are not in the defined_names array
1538                         //
1539                         DefineContainerMembers (instance_constructors);
1540                 
1541                         DefineContainerMembers (events);
1542                         DefineContainerMembers (ordered_explicit_member_list);
1543                         DefineContainerMembers (ordered_member_list);
1544
1545                         DefineContainerMembers (operators);
1546                         DefineContainerMembers (delegates);
1547
1548                         ComputeIndexerName();
1549                         CheckEqualsAndGetHashCode();
1550
1551                         if (CurrentType != null) {
1552                                 GenericType = CurrentType;
1553                         }
1554
1555 #if CACHE
1556                         member_cache = new MemberCache (this);
1557                         if (partial_parts != null) {
1558                                 foreach (TypeContainer part in partial_parts)
1559                                         part.member_cache = member_cache;
1560                         }
1561 #endif
1562
1563                         return true;
1564                 }
1565
1566                 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
1567                 {
1568                         if (mcal != null)
1569                                 mcal.DefineContainerMembers ();
1570                 }
1571                 
1572                 protected virtual void ComputeIndexerName ()
1573                 {
1574                         if (indexers == null)
1575                                 return;
1576
1577                         string class_indexer_name = null;
1578
1579                         //
1580                         // If there's both an explicit and an implicit interface implementation, the
1581                         // explicit one actually implements the interface while the other one is just
1582                         // a normal indexer.  See bug #37714.
1583                         //
1584
1585                         // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
1586                         foreach (Indexer i in indexers) {
1587                                 if (i.InterfaceType != null) {
1588                                         if (seen_normal_indexers)
1589                                                 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
1590                                         continue;
1591                                 }
1592
1593                                 seen_normal_indexers = true;
1594
1595                                 if (class_indexer_name == null) {
1596                                         class_indexer_name = i.ShortName;
1597                                         continue;
1598                                 }
1599
1600                                 if (i.ShortName != class_indexer_name)
1601                                         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");
1602                         }
1603
1604                         if (class_indexer_name != null)
1605                                 indexer_name = class_indexer_name;
1606                 }
1607
1608                 protected virtual void EmitIndexerName ()
1609                 {
1610                         if (!seen_normal_indexers)
1611                                 return;
1612
1613                         CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
1614                         TypeBuilder.SetCustomAttribute (cb);
1615                 }
1616
1617                 protected virtual void CheckEqualsAndGetHashCode ()
1618                 {
1619                         if (methods == null)
1620                                 return;
1621
1622                         if (HasEquals && !HasGetHashCode) {
1623                                 Report.Warning (659, 3, this.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ());
1624                         }
1625                 }
1626
1627                 public override bool Define ()
1628                 {
1629                         if (compiler_generated != null) {
1630                                 foreach (CompilerGeneratedClass c in compiler_generated) {
1631                                         if (!c.Define ())
1632                                                 return false;
1633                                 }
1634                         }
1635
1636                         return true;
1637                 }
1638
1639                 public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
1640                 {
1641                         return BaseCache == null ? null : BaseCache.FindMemberWithSameName (name, ignore_methods, null);
1642                 }
1643
1644                 /// <summary>
1645                 ///   This function is based by a delegate to the FindMembers routine
1646                 /// </summary>
1647                 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1648                 {
1649                         return true;
1650                 }
1651
1652                 /// <summary>
1653                 ///   This filter is used by FindMembers, and we just keep
1654                 ///   a global for the filter to `AlwaysAccept'
1655                 /// </summary>
1656                 static MemberFilter accepting_filter;
1657
1658                 
1659                 static TypeContainer ()
1660                 {
1661                         accepting_filter = new MemberFilter (AlwaysAccept);
1662                 }
1663
1664                 public MethodInfo[] GetMethods ()
1665                 {
1666                         ArrayList members = new ArrayList ();
1667
1668                         DefineMembers ();
1669
1670                         if (methods != null) {
1671                                 int len = methods.Count;
1672                                 for (int i = 0; i < len; i++) {
1673                                         Method m = (Method) methods [i];
1674
1675                                         members.Add (m.MethodBuilder);
1676                                 }
1677                         }
1678
1679                         if (operators != null) {
1680                                 int len = operators.Count;
1681                                 for (int i = 0; i < len; i++) {
1682                                         Operator o = (Operator) operators [i];
1683
1684                                         members.Add (o.MethodBuilder);
1685                                 }
1686                         }
1687
1688                         if (properties != null) {
1689                                 int len = properties.Count;
1690                                 for (int i = 0; i < len; i++) {
1691                                         Property p = (Property) properties [i];
1692
1693                                         if (p.GetBuilder != null)
1694                                                 members.Add (p.GetBuilder);
1695                                         if (p.SetBuilder != null)
1696                                                 members.Add (p.SetBuilder);
1697                                 }
1698                         }
1699                                 
1700                         if (indexers != null) {
1701                                 int len = indexers.Count;
1702                                 for (int i = 0; i < len; i++) {
1703                                         Indexer ix = (Indexer) indexers [i];
1704
1705                                         if (ix.GetBuilder != null)
1706                                                 members.Add (ix.GetBuilder);
1707                                         if (ix.SetBuilder != null)
1708                                                 members.Add (ix.SetBuilder);
1709                                 }
1710                         }
1711
1712                         if (events != null) {
1713                                 int len = events.Count;
1714                                 for (int i = 0; i < len; i++) {
1715                                         Event e = (Event) events [i];
1716
1717                                         if (e.AddBuilder != null)
1718                                                 members.Add (e.AddBuilder);
1719                                         if (e.RemoveBuilder != null)
1720                                                 members.Add (e.RemoveBuilder);
1721                                 }
1722                         }
1723
1724                         MethodInfo[] retMethods = new MethodInfo [members.Count];
1725                         members.CopyTo (retMethods, 0);
1726                         return retMethods;
1727                 }
1728                 
1729                 // Indicated whether container has StructLayout attribute set Explicit
1730                 public bool HasExplicitLayout {
1731                         get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
1732                         set { caching_flags |= Flags.HasExplicitLayout; }
1733                 }
1734
1735                 //
1736                 // Return the nested type with name @name.  Ensures that the nested type
1737                 // is defined if necessary.  Do _not_ use this when you have a MemberCache handy.
1738                 //
1739                 public Type FindNestedType (string name)
1740                 {
1741                         if (PartialContainer != this)
1742                                 throw new InternalErrorException ("should not happen");
1743
1744                         ArrayList [] lists = { types, delegates };
1745
1746                         for (int j = 0; j < lists.Length; ++j) {
1747                                 ArrayList list = lists [j];
1748                                 if (list == null)
1749                                         continue;
1750                                 
1751                                 int len = list.Count;
1752                                 for (int i = 0; i < len; ++i) {
1753                                         DeclSpace ds = (DeclSpace) list [i];
1754                                         if (ds.Basename == name) {
1755                                                 return ds.DefineType ();
1756                                         }
1757                                 }
1758                         }
1759
1760                         return null;
1761                 }
1762
1763                 private void FindMembers_NestedTypes (int modflags,
1764                                                       BindingFlags bf, MemberFilter filter, object criteria,
1765                                                       ref ArrayList members)
1766                 {
1767                         ArrayList [] lists = { types, delegates };
1768
1769                         for (int j = 0; j < lists.Length; ++j) {
1770                                 ArrayList list = lists [j];
1771                                 if (list == null)
1772                                         continue;
1773                         
1774                                 int len = list.Count;
1775                                 for (int i = 0; i < len; i++) {
1776                                         DeclSpace ds = (DeclSpace) list [i];
1777                                         
1778                                         if ((ds.ModFlags & modflags) == 0)
1779                                                 continue;
1780                                         
1781                                         TypeBuilder tb = ds.TypeBuilder;
1782                                         if (tb == null) {
1783                                                 if (!(criteria is string) || ds.Basename.Equals (criteria))
1784                                                         tb = ds.DefineType ();
1785                                         }
1786                                         
1787                                         if (tb != null && (filter (tb, criteria) == true)) {
1788                                                 if (members == null)
1789                                                         members = new ArrayList ();
1790                                                 
1791                                                 members.Add (tb);
1792                                         }
1793                                 }
1794                         }
1795                 }
1796                 
1797                 /// <summary>
1798                 ///   This method returns the members of this type just like Type.FindMembers would
1799                 ///   Only, we need to use this for types which are _being_ defined because MS' 
1800                 ///   implementation can't take care of that.
1801                 /// </summary>
1802                 //
1803                 // FIXME: return an empty static array instead of null, that cleans up
1804                 // some code and is consistent with some coding conventions I just found
1805                 // out existed ;-)
1806                 //
1807                 //
1808                 // Notice that in various cases we check if our field is non-null,
1809                 // something that would normally mean that there was a bug elsewhere.
1810                 //
1811                 // The problem happens while we are defining p-invoke methods, as those
1812                 // will trigger a FindMembers, but this happens before things are defined
1813                 //
1814                 // Since the whole process is a no-op, it is fine to check for null here.
1815                 //
1816                 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1817                                                         MemberFilter filter, object criteria)
1818                 {
1819                         ArrayList members = null;
1820
1821                         int modflags = 0;
1822                         if ((bf & BindingFlags.Public) != 0)
1823                                 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1824                                         Modifiers.INTERNAL;
1825                         if ((bf & BindingFlags.NonPublic) != 0)
1826                                 modflags |= Modifiers.PRIVATE;
1827
1828                         int static_mask = 0, static_flags = 0;
1829                         switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1830                         case BindingFlags.Static:
1831                                 static_mask = static_flags = Modifiers.STATIC;
1832                                 break;
1833
1834                         case BindingFlags.Instance:
1835                                 static_mask = Modifiers.STATIC;
1836                                 static_flags = 0;
1837                                 break;
1838
1839                         default:
1840                                 static_mask = static_flags = 0;
1841                                 break;
1842                         }
1843
1844                         Timer.StartTimer (TimerType.TcFindMembers);
1845
1846                         if (filter == null)
1847                                 filter = accepting_filter; 
1848
1849                         if ((mt & MemberTypes.Field) != 0) {
1850                                 if (fields != null) {
1851                                         int len = fields.Count;
1852                                         for (int i = 0; i < len; i++) {
1853                                                 FieldBase f = (FieldBase) fields [i];
1854                                                 
1855                                                 if ((f.ModFlags & modflags) == 0)
1856                                                         continue;
1857                                                 if ((f.ModFlags & static_mask) != static_flags)
1858                                                         continue;
1859
1860                                                 FieldBuilder fb = f.FieldBuilder;
1861                                                 if (fb != null && filter (fb, criteria) == true) {
1862                                                         if (members == null)
1863                                                                 members = new ArrayList ();
1864                                                         
1865                                                         members.Add (fb);
1866                                                 }
1867                                         }
1868                                 }
1869
1870                                 if (constants != null) {
1871                                         int len = constants.Count;
1872                                         for (int i = 0; i < len; i++) {
1873                                                 Const con = (Const) constants [i];
1874                                                 
1875                                                 if ((con.ModFlags & modflags) == 0)
1876                                                         continue;
1877                                                 if ((con.ModFlags & static_mask) != static_flags)
1878                                                         continue;
1879
1880                                                 FieldBuilder fb = con.FieldBuilder;
1881                                                 if (fb == null) {
1882                                                         if (con.Define ())
1883                                                                 fb = con.FieldBuilder;
1884                                                 }
1885                                                 if (fb != null && filter (fb, criteria) == true) {
1886                                                         if (members == null)
1887                                                                 members = new ArrayList ();
1888                                                         
1889                                                         members.Add (fb);
1890                                                 }
1891                                         }
1892                                 }
1893                         }
1894
1895                         if ((mt & MemberTypes.Method) != 0) {
1896                                 if (methods != null) {
1897                                         int len = methods.Count;
1898                                         for (int i = 0; i < len; i++) {
1899                                                 Method m = (Method) methods [i];
1900                                                 
1901                                                 if ((m.ModFlags & modflags) == 0)
1902                                                         continue;
1903                                                 if ((m.ModFlags & static_mask) != static_flags)
1904                                                         continue;
1905                                                 
1906                                                 MethodBuilder mb = m.MethodBuilder;
1907
1908                                                 if (mb != null && filter (mb, criteria) == true) {
1909                                                         if (members == null)
1910                                                                 members = new ArrayList ();
1911                                                         
1912                                                         members.Add (mb);
1913                                                 }
1914                                         }
1915                                 }
1916
1917                                 if (operators != null) {
1918                                         int len = operators.Count;
1919                                         for (int i = 0; i < len; i++) {
1920                                                 Operator o = (Operator) operators [i];
1921                                                 
1922                                                 if ((o.ModFlags & modflags) == 0)
1923                                                         continue;
1924                                                 if ((o.ModFlags & static_mask) != static_flags)
1925                                                         continue;
1926                                                 
1927                                                 MethodBuilder ob = o.MethodBuilder;
1928                                                 if (ob != null && filter (ob, criteria) == true) {
1929                                                         if (members == null)
1930                                                                 members = new ArrayList ();
1931                                                         
1932                                                         members.Add (ob);
1933                                                 }
1934                                         }
1935                                 }
1936
1937                                 if (events != null) {
1938                                         foreach (Event e in events) {
1939                                                 if ((e.ModFlags & modflags) == 0)
1940                                                         continue;
1941                                                 if ((e.ModFlags & static_mask) != static_flags)
1942                                                         continue;
1943
1944                                                 MethodBuilder b = e.AddBuilder;
1945                                                 if (b != null && filter (b, criteria)) {
1946                                                         if (members == null)
1947                                                                 members = new ArrayList (4);
1948
1949                                                         members.Add (b);
1950                                                 }
1951
1952                                                 b = e.RemoveBuilder;
1953                                                 if (b != null && filter (b, criteria)) {
1954                                                         if (members == null) 
1955                                                                 members = new ArrayList (4);
1956
1957                                                         members.Add (b);
1958                                                 }
1959                                         }
1960                                 }
1961
1962                                 if (properties != null) {
1963                                         int len = properties.Count;
1964                                         for (int i = 0; i < len; i++) {
1965                                                 Property p = (Property) properties [i];
1966                                                 
1967                                                 if ((p.ModFlags & modflags) == 0)
1968                                                         continue;
1969                                                 if ((p.ModFlags & static_mask) != static_flags)
1970                                                         continue;
1971                                                 
1972                                                 MethodBuilder b;
1973
1974                                                 b = p.GetBuilder;
1975                                                 if (b != null && filter (b, criteria) == true) {
1976                                                         if (members == null)
1977                                                                 members = new ArrayList ();
1978                                                         
1979                                                         members.Add (b);
1980                                                 }
1981
1982                                                 b = p.SetBuilder;
1983                                                 if (b != null && filter (b, criteria) == true) {
1984                                                         if (members == null)
1985                                                                 members = new ArrayList ();
1986                                                         
1987                                                         members.Add (b);
1988                                                 }
1989                                         }
1990                                 }
1991                                 
1992                                 if (indexers != null) {
1993                                         int len = indexers.Count;
1994                                         for (int i = 0; i < len; i++) {
1995                                                 Indexer ix = (Indexer) indexers [i];
1996                                                 
1997                                                 if ((ix.ModFlags & modflags) == 0)
1998                                                         continue;
1999                                                 if ((ix.ModFlags & static_mask) != static_flags)
2000                                                         continue;
2001                                                 
2002                                                 MethodBuilder b;
2003
2004                                                 b = ix.GetBuilder;
2005                                                 if (b != null && filter (b, criteria) == true) {
2006                                                         if (members == null)
2007                                                                 members = new ArrayList ();
2008                                                         
2009                                                         members.Add (b);
2010                                                 }
2011
2012                                                 b = ix.SetBuilder;
2013                                                 if (b != null && filter (b, criteria) == true) {
2014                                                         if (members == null)
2015                                                                 members = new ArrayList ();
2016                                                         
2017                                                         members.Add (b);
2018                                                 }
2019                                         }
2020                                 }
2021                         }
2022
2023                         if ((mt & MemberTypes.Event) != 0) {
2024                                 if (events != null) {
2025                                         int len = events.Count;
2026                                         for (int i = 0; i < len; i++) {
2027                                                 Event e = (Event) events [i];
2028                                                 
2029                                                 if ((e.ModFlags & modflags) == 0)
2030                                                         continue;
2031                                                 if ((e.ModFlags & static_mask) != static_flags)
2032                                                         continue;
2033
2034                                                 MemberInfo eb = e.EventBuilder;
2035                                                 if (eb != null && filter (eb, criteria) == true) {
2036                                                         if (members == null)
2037                                                                 members = new ArrayList ();
2038                                                         
2039                                                         members.Add (e.EventBuilder);
2040                                                 }
2041                                         }
2042                                 }
2043                         }
2044                         
2045                         if ((mt & MemberTypes.Property) != 0){
2046                                 if (properties != null) {
2047                                         int len = properties.Count;
2048                                         for (int i = 0; i < len; i++) {
2049                                                 Property p = (Property) properties [i];
2050                                                 
2051                                                 if ((p.ModFlags & modflags) == 0)
2052                                                         continue;
2053                                                 if ((p.ModFlags & static_mask) != static_flags)
2054                                                         continue;
2055
2056                                                 MemberInfo pb = p.PropertyBuilder;
2057                                                 if (pb != null && filter (pb, criteria) == true) {
2058                                                         if (members == null)
2059                                                                 members = new ArrayList ();
2060                                                         
2061                                                         members.Add (p.PropertyBuilder);
2062                                                 }
2063                                         }
2064                                 }
2065
2066                                 if (indexers != null) {
2067                                         int len = indexers.Count;
2068                                         for (int i = 0; i < len; i++) {
2069                                                 Indexer ix = (Indexer) indexers [i];
2070                                                 
2071                                                 if ((ix.ModFlags & modflags) == 0)
2072                                                         continue;
2073                                                 if ((ix.ModFlags & static_mask) != static_flags)
2074                                                         continue;
2075
2076                                                 MemberInfo ib = ix.PropertyBuilder;
2077                                                 if (ib != null && filter (ib, criteria) == true) {
2078                                                         if (members == null)
2079                                                                 members = new ArrayList ();
2080                                                         
2081                                                         members.Add (ix.PropertyBuilder);
2082                                                 }
2083                                         }
2084                                 }
2085                         }
2086                         
2087                         if ((mt & MemberTypes.NestedType) != 0)
2088                                 FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
2089
2090                         if ((mt & MemberTypes.Constructor) != 0){
2091                                 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
2092                                         int len = instance_constructors.Count;
2093                                         for (int i = 0; i < len; i++) {
2094                                                 Constructor c = (Constructor) instance_constructors [i];
2095                                                 
2096                                                 ConstructorBuilder cb = c.ConstructorBuilder;
2097                                                 if (cb != null && filter (cb, criteria) == true) {
2098                                                         if (members == null)
2099                                                                 members = new ArrayList ();
2100                                                         
2101                                                         members.Add (cb);
2102                                                 }
2103                                         }
2104                                 }
2105
2106                                 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
2107                                         ConstructorBuilder cb =
2108                                                 default_static_constructor.ConstructorBuilder;
2109                                         
2110                                         if (cb != null && filter (cb, criteria) == true) {
2111                                                 if (members == null)
2112                                                         members = new ArrayList ();
2113                                                 
2114                                                 members.Add (cb);
2115                                         }
2116                                 }
2117                         }
2118
2119                         //
2120                         // Lookup members in base if requested.
2121                         //
2122                         if ((bf & BindingFlags.DeclaredOnly) == 0) {
2123                                 if (TypeBuilder.BaseType != null) {
2124                                         MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
2125                                         if (list.Count > 0) {
2126                                                 if (members == null)
2127                                                         members = new ArrayList ();
2128                                         
2129                                                 members.AddRange (list);
2130                                         }
2131                                 }
2132                         }
2133
2134                         Timer.StopTimer (TimerType.TcFindMembers);
2135
2136                         if (members == null)
2137                                 return MemberList.Empty;
2138                         else
2139                                 return new MemberList (members);
2140                 }
2141
2142                 public override MemberCache MemberCache {
2143                         get {
2144                                 return member_cache;
2145                         }
2146                 }
2147
2148                 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
2149                                                       MemberFilter filter, object criteria)
2150                 {
2151                         DeclSpace ds = TypeManager.LookupDeclSpace (t);
2152
2153                         if (ds != null)
2154                                 return ds.FindMembers (mt, bf, filter, criteria);
2155                         else
2156                                 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
2157                 }
2158
2159                 /// <summary>
2160                 ///   Emits the values for the constants
2161                 /// </summary>
2162                 public void EmitConstants ()
2163                 {
2164                         if (constants != null)
2165                                 foreach (Const con in constants)
2166                                         con.Emit ();
2167                         return;
2168                 }
2169
2170                 static void CheckMemberUsage (MemberCoreArrayList al, string member_type)
2171                 {
2172                         if (al == null)
2173                                 return;
2174
2175                         foreach (MemberCore mc in al) {
2176                                 if ((mc.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2177                                         continue;
2178
2179                                 if (!mc.IsUsed) {
2180                                         Report.Warning (169, 3, mc.Location, "The private {0} `{1}' is never used", member_type, mc.GetSignatureForError ());
2181                                 }
2182                         }
2183                 }
2184
2185                 public virtual void VerifyMembers ()
2186                 {
2187                         //
2188                         // Check for internal or private fields that were never assigned
2189                         //
2190                         if (Report.WarningLevel >= 3) {
2191                                 CheckMemberUsage (properties, "property");
2192                                 CheckMemberUsage (methods, "method");
2193                                 CheckMemberUsage (constants, "constant");
2194
2195                                 if (fields != null){
2196                                         foreach (FieldBase f in fields) {
2197                                                 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2198                                                         continue;
2199                                                 
2200                                                 if (!f.IsUsed){
2201                                                         if ((f.caching_flags & Flags.IsAssigned) == 0)
2202                                                                 Report.Warning (169, 3, f.Location, "The private field `{0}' is never used", f.GetSignatureForError ());
2203                                                         else {
2204 #if NET_2_0
2205                                                                 const int error_code = 414;
2206 #else
2207                                                                 const int error_code = 169;
2208 #endif
2209                                                                 Report.Warning (error_code, 3, f.Location, "The private field `{0}' is assigned but its value is never used",
2210                                                                         f.GetSignatureForError ());
2211                                                         }
2212                                                         continue;
2213                                                 }
2214                                                 
2215                                                 //
2216                                                 // Only report 649 on level 4
2217                                                 //
2218                                                 if (Report.WarningLevel < 4)
2219                                                         continue;
2220                                                 
2221                                                 if ((f.caching_flags & Flags.IsAssigned) != 0)
2222                                                         continue;
2223                                                 
2224                                                 Constant c = New.Constantify (f.Type.Type);
2225                                                 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2226                                                         f.GetSignatureForError (), c == null ? "null" : c.AsString ());
2227                                         }
2228                                 }
2229                         }
2230                 }
2231
2232                 // TODO: move to ClassOrStruct
2233                 void EmitConstructors ()
2234                 {
2235                         if (instance_constructors == null)
2236                                 return;
2237
2238                         if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsComplianceRequired ()) {
2239                                 bool has_compliant_args = false;
2240
2241                                 foreach (Constructor c in instance_constructors) {
2242                                         try {
2243                                                 c.Emit ();
2244                                         }
2245                                         catch (Exception e) {
2246                                                 throw new InternalErrorException (c, e);
2247                                         }
2248
2249                                         if (has_compliant_args)
2250                                                 continue;
2251
2252                                         has_compliant_args = c.HasCompliantArgs;
2253                                 }
2254                                 if (!has_compliant_args)
2255                                         Report.Error (3015, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2256                         } else {
2257                                 foreach (Constructor c in instance_constructors) {
2258                                         try {
2259                                                 c.Emit ();
2260                                         }
2261                                         catch (Exception e) {
2262                                                 throw new InternalErrorException (c, e);
2263                                         }
2264                                 }
2265                         }
2266                 }
2267
2268                 /// <summary>
2269                 ///   Emits the code, this step is performed after all
2270                 ///   the types, enumerations, constructors
2271                 /// </summary>
2272                 public virtual void EmitType ()
2273                 {
2274                         if (OptAttributes != null)
2275                                 OptAttributes.Emit ();
2276
2277 #if GMCS_SOURCE
2278                         if (IsGeneric) {
2279                                 int offset = CountTypeParameters - CurrentTypeParameters.Length;
2280                                 for (int i = offset; i < gen_params.Length; i++)
2281                                         CurrentTypeParameters [i - offset].EmitAttributes ();
2282                         }
2283 #endif
2284
2285                         //
2286                         // Structs with no fields need to have at least one byte.
2287                         // The right thing would be to set the PackingSize in a DefineType
2288                         // but there are no functions that allow interfaces *and* the size to
2289                         // be specified.
2290                         //
2291
2292                         if (Kind == Kind.Struct && first_nonstatic_field == null){
2293                                 FieldBuilder fb = TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
2294                                                                            FieldAttributes.Private);
2295
2296                                 if (HasExplicitLayout){
2297                                         object [] ctor_args = new object [1];
2298                                         ctor_args [0] = 0;
2299                                 
2300                                         CustomAttributeBuilder cba = new CustomAttributeBuilder (
2301                                                 TypeManager.field_offset_attribute_ctor, ctor_args);
2302                                         fb.SetCustomAttribute (cba);
2303                                 }
2304                         }
2305
2306                         Emit ();
2307
2308                         EmitConstructors ();
2309
2310                         // Can not continue if constants are broken
2311                         EmitConstants ();
2312                         if (Report.Errors > 0)
2313                                 return;
2314
2315                         if (default_static_constructor != null)
2316                                 default_static_constructor.Emit ();
2317                         
2318                         if (methods != null){
2319                                 for (int i = 0; i < methods.Count; ++i)
2320                                         ((Method)methods[i]).Emit ();
2321                         }
2322
2323                         if (operators != null)
2324                                 foreach (Operator o in operators)
2325                                         o.Emit ();
2326
2327                         if (properties != null)
2328                                 foreach (Property p in properties)
2329                                         p.Emit ();
2330
2331                         if (indexers != null) {
2332                                 foreach (Indexer indx in indexers)
2333                                         indx.Emit ();
2334                                 EmitIndexerName ();
2335                         }
2336                         
2337                         if (fields != null)
2338                                 foreach (FieldBase f in fields)
2339                                         f.Emit ();
2340
2341                         if (events != null){
2342                                 foreach (Event e in Events)
2343                                         e.Emit ();
2344                         }
2345
2346                         if (delegates != null) {
2347                                 foreach (Delegate d in Delegates) {
2348                                         d.Emit ();
2349                                 }
2350                         }
2351
2352                         if (pending != null)
2353                                 if (pending.VerifyPendingMethods ())
2354                                         return;
2355
2356                         if (Report.Errors > 0)
2357                                 return;
2358
2359                         if (compiler_generated != null) {
2360                                 foreach (CompilerGeneratedClass c in compiler_generated) {
2361                                         if (!c.DefineMembers ())
2362                                                 throw new InternalErrorException ();
2363                                 }
2364                                 foreach (CompilerGeneratedClass c in compiler_generated)
2365                                         c.EmitType ();
2366                         }
2367                 }
2368                 
2369                 public override void CloseType ()
2370                 {
2371                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
2372                                 return;
2373
2374                         try {
2375                                 caching_flags |= Flags.CloseTypeCreated;
2376                                 TypeBuilder.CreateType ();
2377                         } catch (TypeLoadException){
2378                                 //
2379                                 // This is fine, the code still created the type
2380                                 //
2381 //                              Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2382 //                              Console.WriteLine (e.Message);
2383                         } catch (Exception e) {
2384                                 throw new InternalErrorException (this, e);
2385                         }
2386                         
2387                         if (Types != null){
2388                                 foreach (TypeContainer tc in Types)
2389                                         if (tc.Kind == Kind.Struct)
2390                                                 tc.CloseType ();
2391
2392                                 foreach (TypeContainer tc in Types)
2393                                         if (tc.Kind != Kind.Struct)
2394                                                 tc.CloseType ();
2395                         }
2396
2397                         if (Delegates != null)
2398                                 foreach (Delegate d in Delegates)
2399                                         d.CloseType ();
2400
2401                         if (CompilerGenerated != null)
2402                                 foreach (CompilerGeneratedClass c in CompilerGenerated)
2403                                         c.CloseType ();
2404                         
2405                         types = null;
2406                         properties = null;
2407                         delegates = null;
2408                         fields = null;
2409                         initialized_fields = null;
2410                         initialized_static_fields = null;
2411                         constants = null;
2412                         ordered_explicit_member_list = null;
2413                         ordered_member_list = null;
2414                         methods = null;
2415                         events = null;
2416                         indexers = null;
2417                         operators = null;
2418                         compiler_generated = null;
2419                         default_constructor = null;
2420                         default_static_constructor = null;
2421                         type_bases = null;
2422                         OptAttributes = null;
2423                         ifaces = null;
2424                         base_cache = null;
2425                         member_cache = null;
2426                 }
2427
2428                 //
2429                 // Performs the validation on a Method's modifiers (properties have
2430                 // the same properties).
2431                 //
2432                 public bool MethodModifiersValid (MemberCore mc)
2433                 {
2434                         const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2435                         const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2436                         const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2437                         bool ok = true;
2438                         int flags = mc.ModFlags;
2439                         
2440                         //
2441                         // At most one of static, virtual or override
2442                         //
2443                         if ((flags & Modifiers.STATIC) != 0){
2444                                 if ((flags & vao) != 0){
2445                                         Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2446                                                 mc.GetSignatureForError ());
2447                                         ok = false;
2448                                 }
2449                         }
2450
2451                         if (Kind == Kind.Struct){
2452                                 if ((flags & va) != 0){
2453                                         Modifiers.Error_InvalidModifier (mc.Location, "virtual or abstract");
2454                                         ok = false;
2455                                 }
2456                         }
2457
2458                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2459                                 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2460                                         mc.GetSignatureForError ());
2461                                 ok = false;
2462                         }
2463
2464                         //
2465                         // If the declaration includes the abstract modifier, then the
2466                         // declaration does not include static, virtual or extern
2467                         //
2468                         if ((flags & Modifiers.ABSTRACT) != 0){
2469                                 if ((flags & Modifiers.EXTERN) != 0){
2470                                         Report.Error (
2471                                                 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2472                                         ok = false;
2473                                 }
2474
2475                                 if ((flags & Modifiers.SEALED) != 0) {
2476                                         Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2477                                         ok = false;
2478                                 }
2479
2480                                 if ((flags & Modifiers.VIRTUAL) != 0){
2481                                         Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2482                                         ok = false;
2483                                 }
2484
2485                                 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2486                                         Report.SymbolRelatedToPreviousError (this);
2487                                         Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2488                                                 mc.GetSignatureForError (), GetSignatureForError ());
2489                                         ok = false;
2490                                 }
2491                         }
2492
2493                         if ((flags & Modifiers.PRIVATE) != 0){
2494                                 if ((flags & vao) != 0){
2495                                         Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2496                                         ok = false;
2497                                 }
2498                         }
2499
2500                         if ((flags & Modifiers.SEALED) != 0){
2501                                 if ((flags & Modifiers.OVERRIDE) == 0){
2502                                         Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2503                                         ok = false;
2504                                 }
2505                         }
2506
2507                         return ok;
2508                 }
2509
2510                 public Constructor DefaultStaticConstructor {
2511                         get { return default_static_constructor; }
2512                 }
2513
2514                 protected override bool VerifyClsCompliance ()
2515                 {
2516                         if (!base.VerifyClsCompliance ())
2517                                 return false;
2518
2519                         VerifyClsName ();
2520
2521                         Type base_type = TypeBuilder.BaseType;
2522                         if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
2523                                 Report.Error (3009, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
2524                         }
2525                         return true;
2526                 }
2527
2528
2529                 /// <summary>
2530                 /// Checks whether container name is CLS Compliant
2531                 /// </summary>
2532                 void VerifyClsName ()
2533                 {
2534                         Hashtable base_members = base_cache == null ? 
2535                                 new Hashtable () :
2536                                 base_cache.GetPublicMembers ();
2537                         Hashtable this_members = new Hashtable ();
2538
2539                         foreach (DictionaryEntry entry in defined_names) {
2540                                 MemberCore mc = (MemberCore)entry.Value;
2541                                 if (!mc.IsClsComplianceRequired ())
2542                                         continue;
2543
2544                                 string name = (string) entry.Key;
2545                                 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2546
2547                                 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2548                                 object found = base_members [lcase];
2549                                 if (found == null) {
2550                                         found = this_members [lcase];
2551                                         if (found == null) {
2552                                                 this_members.Add (lcase, mc);
2553                                                 continue;
2554                                         }
2555                                 }
2556
2557                                 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2558                                         continue;                                       
2559
2560                                 if (found is MemberInfo) {
2561                                         if (basename == ((MemberInfo) found).Name)
2562                                                 continue;
2563                                         Report.SymbolRelatedToPreviousError ((MemberInfo) found);
2564                                 } else {
2565                                         Report.SymbolRelatedToPreviousError ((MemberCore) found);
2566                                 }
2567 #if GMCS_SOURCE
2568                                 Report.Warning (3005, 1, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2569 #else
2570                                 Report.Error (3005, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2571 #endif
2572                         }
2573                 }
2574
2575
2576                 /// <summary>
2577                 ///   Performs checks for an explicit interface implementation.  First it
2578                 ///   checks whether the `interface_type' is a base inteface implementation.
2579                 ///   Then it checks whether `name' exists in the interface type.
2580                 /// </summary>
2581                 public virtual bool VerifyImplements (InterfaceMemberBase mb)
2582                 {
2583                         if (ifaces != null) {
2584                                 foreach (Type t in ifaces){
2585                                         if (t == mb.InterfaceType)
2586                                                 return true;
2587                                 }
2588                         }
2589                         
2590                         Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2591                         Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2592                                 mb.GetSignatureForError (), TypeManager.CSharpName (mb.InterfaceType));
2593                         return false;
2594                 }
2595
2596                 public override Type LookupAnyGeneric (string typeName)
2597                 {
2598                         if (types != null) {
2599                                 foreach (TypeContainer tc in types) {
2600                                         if (!tc.IsGeneric)
2601                                                 continue;
2602
2603                                         int pos = tc.Basename.LastIndexOf ('`');
2604                                         if (pos == typeName.Length && String.Compare (typeName, 0, tc.Basename, 0, pos) == 0)
2605                                                 return tc.TypeBuilder;
2606                                 }
2607                         }
2608
2609                         return base.LookupAnyGeneric (typeName);
2610                 }
2611
2612                 public void Mark_HasEquals ()
2613                 {
2614                         cached_method |= CachedMethods.Equals;
2615                 }
2616
2617                 public void Mark_HasGetHashCode ()
2618                 {
2619                         cached_method |= CachedMethods.GetHashCode;
2620                 }
2621
2622                 /// <summary>
2623                 /// Method container contains Equals method
2624                 /// </summary>
2625                 public bool HasEquals {
2626                         get {
2627                                 return (cached_method & CachedMethods.Equals) != 0;
2628                         }
2629                 }
2630  
2631                 /// <summary>
2632                 /// Method container contains GetHashCode method
2633                 /// </summary>
2634                 public bool HasGetHashCode {
2635                         get {
2636                                 return (cached_method & CachedMethods.GetHashCode) != 0;
2637                         }
2638                 }
2639
2640                 //
2641                 // IMemberContainer
2642                 //
2643
2644                 string IMemberContainer.Name {
2645                         get {
2646                                 return Name;
2647                         }
2648                 }
2649
2650                 Type IMemberContainer.Type {
2651                         get {
2652                                 return TypeBuilder;
2653                         }
2654                 }
2655
2656                 MemberCache IMemberContainer.MemberCache {
2657                         get {
2658                                 return member_cache;
2659                         }
2660                 }
2661
2662                 bool IMemberContainer.IsInterface {
2663                         get {
2664                                 return Kind == Kind.Interface;
2665                         }
2666                 }
2667
2668                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2669                 {
2670                         BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
2671
2672                         if (GenericType != null)
2673                                 return TypeManager.FindMembers (GenericType, mt, new_bf,
2674                                                                 null, null);
2675                         else
2676                                 return FindMembers (mt, new_bf, null, null);
2677                 }
2678
2679                 //
2680                 // Generates xml doc comments (if any), and if required,
2681                 // handle warning report.
2682                 //
2683                 internal override void GenerateDocComment (DeclSpace ds)
2684                 {
2685                         DocUtil.GenerateTypeDocComment (this, ds);
2686                 }
2687
2688                 public override string DocCommentHeader {
2689                         get { return "T:"; }
2690                 }
2691
2692                 public virtual MemberCache BaseCache {
2693                         get {
2694                                 if (base_cache != null)
2695                                         return base_cache;
2696                                 if (TypeBuilder.BaseType != null)
2697                                         base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
2698                                 if (TypeBuilder.IsInterface)
2699                                         base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
2700                                 return base_cache;
2701                         }
2702                 }
2703         }
2704
2705         public abstract class ClassOrStruct : TypeContainer {
2706                 ListDictionary declarative_security;
2707
2708                 public ClassOrStruct (NamespaceEntry ns, DeclSpace parent,
2709                                       MemberName name, Attributes attrs, Kind kind)
2710                         : base (ns, parent, name, attrs, kind)
2711                 {
2712                 }
2713
2714                 protected override bool AddToContainer (MemberCore symbol, string name)
2715                 {
2716                         if (name == MemberName.Name) {
2717                                 if (symbol is TypeParameter) {
2718                                         Report.Error (694, symbol.Location,
2719                                                       "Type parameter `{0}' has same name as " +
2720                                                       "containing type, or method", name);
2721                                         return false;
2722                                 }
2723
2724                                 Report.SymbolRelatedToPreviousError (this);
2725                                 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2726                                         symbol.GetSignatureForError ());
2727                                 return false;
2728                         }
2729
2730                         return base.AddToContainer (symbol, name);
2731                 }
2732
2733                 public override void VerifyMembers ()
2734                 {
2735                         base.VerifyMembers ();
2736
2737                         if ((events != null) && Report.WarningLevel >= 3) {
2738                                 foreach (Event e in events){
2739                                         if ((e.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2740                                                 continue;
2741
2742                                         if ((e.caching_flags & Flags.IsUsed) == 0)
2743                                                 Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
2744                                 }
2745                         }
2746                 }
2747
2748                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2749                 {
2750                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
2751                                 if (declarative_security == null)
2752                                         declarative_security = new ListDictionary ();
2753
2754                                 a.ExtractSecurityPermissionSet (declarative_security);
2755                                 return;
2756                         }
2757
2758                         if (a.Type == TypeManager.struct_layout_attribute_type && a.GetLayoutKindValue () == LayoutKind.Explicit) {
2759                                 HasExplicitLayout = true;
2760                         }
2761
2762                         base.ApplyAttributeBuilder (a, cb);
2763                 }
2764
2765                 /// <summary>
2766                 /// Defines the default constructors 
2767                 /// </summary>
2768                 protected void DefineDefaultConstructor (bool is_static)
2769                 {
2770                         // The default instance constructor is public
2771                         // If the class is abstract, the default constructor is protected
2772                         // The default static constructor is private
2773
2774                         int mods;
2775                         if (is_static) {
2776                                 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2777                         } else {
2778                                 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2779                         }
2780
2781                         Constructor c = new Constructor (this, MemberName.Name, mods,
2782                                 Parameters.EmptyReadOnlyParameters,
2783                                 new GeneratedBaseInitializer (Location),
2784                                 Location);
2785                         
2786                         AddConstructor (c);
2787                         c.Block = new ToplevelBlock (null, Location);
2788                 }
2789
2790                 void DefineFieldInitializers ()
2791                 {
2792                         if (initialized_fields != null) {
2793                                 for (int i = 0; i < initialized_fields.Count; ++i) {
2794                                         FieldInitializer fi = (FieldInitializer)initialized_fields[i];
2795
2796                                         EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
2797                                                 Location, null, TypeManager.void_type, ModFlags);
2798                                         ec.IsFieldInitializer = true;
2799
2800                                         fi.ResolveStatement (ec);
2801                                         if (fi.IsDefaultInitializer && RootContext.Optimize) {
2802                                                 // Field is re-initialized to its default value => removed
2803                                                 initialized_fields.RemoveAt (i);
2804                                                 --i;
2805                                         }
2806                                 }
2807                         }
2808
2809                         if (initialized_static_fields != null) {
2810                                 bool has_complex_initializer = false;
2811
2812                                 foreach (FieldInitializer fi in initialized_static_fields) {
2813                                         EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
2814                                                 Location, null, TypeManager.void_type, ModFlags);
2815                                         ec.IsStatic = true;
2816                                         ec.IsFieldInitializer = true;
2817
2818                                         fi.ResolveStatement (ec);
2819                                         if (!fi.IsComplexInitializer)
2820                                                 continue;
2821
2822                                         has_complex_initializer = true;
2823                                 }
2824
2825                                 // Need special check to not optimize code like this
2826                                 // static int a = b = 5;
2827                                 // static int b = 0;
2828                                 if (!has_complex_initializer && RootContext.Optimize) {
2829                                         for (int i = 0; i < initialized_static_fields.Count; ++i) {
2830                                                 FieldInitializer fi = (FieldInitializer)initialized_static_fields[i];
2831                                                 if (fi.IsDefaultInitializer) {
2832                                                         initialized_static_fields.RemoveAt (i);
2833                                                         --i;
2834                                                 }
2835                                         }
2836                                 }
2837
2838                                 if (default_static_constructor == null && initialized_static_fields.Count > 0) {
2839                                         DefineDefaultConstructor (true);
2840                                 }
2841                         }
2842
2843                 }
2844
2845                 public override bool Define ()
2846                 {
2847                         DefineFieldInitializers ();
2848
2849                         if (default_static_constructor != null)
2850                                 default_static_constructor.Define ();
2851
2852                         return base.Define ();
2853                 }
2854
2855                 public override void Emit ()
2856                 {
2857                         base.Emit ();
2858
2859                         if (declarative_security != null) {
2860                                 foreach (DictionaryEntry de in declarative_security) {
2861                                         TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2862                                 }
2863                         }
2864                 }
2865
2866                 public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name)
2867                 {
2868                         return NamespaceEntry.LookupExtensionMethod (extensionType, this, name);
2869                 }
2870
2871                 protected override TypeAttributes TypeAttr {
2872                         get {
2873                                 if (default_static_constructor == null)
2874                                         return base.TypeAttr | TypeAttributes.BeforeFieldInit;
2875
2876                                 return base.TypeAttr;
2877                         }
2878                 }
2879         }
2880
2881
2882         // TODO: should be sealed
2883         public class Class : ClassOrStruct {
2884                 const int AllowedModifiers =
2885                         Modifiers.NEW |
2886                         Modifiers.PUBLIC |
2887                         Modifiers.PROTECTED |
2888                         Modifiers.INTERNAL |
2889                         Modifiers.PRIVATE |
2890                         Modifiers.ABSTRACT |
2891                         Modifiers.SEALED |
2892                         Modifiers.STATIC |
2893                         Modifiers.UNSAFE;
2894
2895                 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2896
2897                 public Class (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
2898                               Attributes attrs)
2899                         : base (ns, parent, name, attrs, Kind.Class)
2900                 {
2901                         int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2902                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
2903
2904                         if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
2905                                 Report.FeatureIsNotISO1 (Location, "static classes");
2906                         }
2907                 }
2908
2909                 public override void AddBasesForPart (DeclSpace part, ArrayList bases)
2910                 {
2911                         if (part.Name == "System.Object")
2912                                 Report.Error (537, part.Location,
2913                                         "The class System.Object cannot have a base class or implement an interface.");
2914                         base.AddBasesForPart (part, bases);
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                         try {
4545                                 Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
4546                                 MethodData.Emit (Parent);
4547                                 base.Emit ();
4548                                 
4549                                 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
4550                                         MethodBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
4551                                 
4552                                 Block = null;
4553                                 MethodData = null;
4554                         } catch {
4555                                 Console.WriteLine ("Interna compiler error at {0}: exception caught while emitting {1}",
4556                                                    Location, MethodBuilder);
4557                                 throw;
4558                         }
4559                 }
4560
4561                 public static void Error1599 (Location loc, Type t)
4562                 {
4563                         Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
4564                 }
4565
4566                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4567                 {
4568                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindMemberToOverride (
4569                                 Parent.TypeBuilder, Name, ParameterTypes, GenericMethod, false);
4570
4571                         if (mi == null)
4572                                 return null;
4573
4574                         if (mi.IsSpecialName)
4575                                 return null;
4576
4577                         base_ret_type = mi.ReturnType;
4578                         return mi;
4579                 }
4580
4581                 protected override bool VerifyClsCompliance ()
4582                 {
4583                         if (!base.VerifyClsCompliance ())
4584                                 return false;
4585
4586                         if (ParameterInfo.Count > 0) {
4587                                 ArrayList al = (ArrayList)Parent.PartialContainer.MemberCache.Members [Name];
4588                                 if (al.Count > 1)
4589                                         MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
4590                         }
4591
4592                         return true;
4593                 }
4594         }
4595
4596         public abstract class ConstructorInitializer {
4597                 readonly ArrayList argument_list;
4598                 MethodGroupExpr base_constructor_group;
4599                 readonly Location loc;
4600                 
4601                 public ConstructorInitializer (ArrayList argument_list, Location loc)
4602                 {
4603                         this.argument_list = argument_list;
4604                         this.loc = loc;
4605                 }
4606
4607                 public ArrayList Arguments {
4608                         get {
4609                                 return argument_list;
4610                         }
4611                 }
4612
4613                 public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
4614                 {
4615                         Type t;
4616
4617                         ec.CurrentBlock = block;
4618
4619                         if (argument_list != null){
4620                                 foreach (Argument a in argument_list){
4621                                         if (!a.Resolve (ec, loc))
4622                                                 return false;
4623                                 }
4624                         }
4625                         ec.CurrentBlock = null;
4626
4627                         if (this is ConstructorBaseInitializer) {
4628                                 if (ec.ContainerType.BaseType == null)
4629                                         return true;
4630
4631                                 t = ec.ContainerType.BaseType;
4632                                 if (ec.ContainerType.IsValueType) {
4633                                         Report.Error (522, loc,
4634                                                 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4635                                         return false;
4636                                 }
4637                         } else {
4638                                 //
4639                                 // It is legal to have "this" initializers that take no arguments
4640                                 // in structs, they are just no-ops.
4641                                 //
4642                                 // struct D { public D (int a) : this () {}
4643                                 //
4644                                 if (ec.ContainerType.IsValueType && argument_list == null)
4645                                         return true;
4646                                 
4647                                 t = ec.ContainerType;
4648                         }
4649
4650                         base_constructor_group = Expression.MemberLookup (
4651                                 ec.ContainerType, t, ".ctor", MemberTypes.Constructor,
4652                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4653                                 loc) as MethodGroupExpr;
4654                         
4655                         bool error_non_public = false;
4656                         if (base_constructor_group == null) {
4657                                 error_non_public = true;
4658                                 base_constructor_group = Expression.MemberLookup (
4659                                     ec.ContainerType, t, ".ctor", MemberTypes.Constructor,
4660                                     BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4661                                     loc) as MethodGroupExpr;
4662                                 
4663                                 // TODO: because of MemberLookup is so broken. It does not return private members
4664                                 // even if you ask for them.
4665                                 if (base_constructor_group == null) {
4666                                         Expression.MemberLookupFailed (ec.ContainerType, t, t, ".ctor", null, true, loc);
4667                                         return false;
4668                                 }                                       
4669                         }
4670
4671                         base_constructor_group = base_constructor_group.OverloadResolve (
4672                                 ec, argument_list, false, loc);
4673                         
4674                         if (base_constructor_group == null)
4675                                 return false;
4676
4677                         ConstructorInfo base_ctor = (ConstructorInfo)base_constructor_group;
4678                         
4679                         if (base_ctor == caller_builder){
4680                                 Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4681                         }
4682                         
4683                         if (error_non_public) {
4684                                 Report.SymbolRelatedToPreviousError (base_ctor);
4685                                 Expression.ErrorIsInaccesible (loc, TypeManager.CSharpSignature (base_ctor));
4686                         }                       
4687                         
4688                         return true;
4689                 }
4690
4691                 public void Emit (EmitContext ec)
4692                 {
4693                         // It can be null for static initializers
4694                         if (base_constructor_group == null)
4695                                 return;
4696                         
4697                         ec.Mark (loc, false);
4698                         if (!ec.IsStatic)
4699                                 base_constructor_group.InstanceExpression = ec.GetThis (loc);
4700                         
4701                         base_constructor_group.EmitCall (ec, argument_list);
4702                 }
4703         }
4704
4705         public class ConstructorBaseInitializer : ConstructorInitializer {
4706                 public ConstructorBaseInitializer (ArrayList argument_list, Location l) :
4707                         base (argument_list, l)
4708                 {
4709                 }
4710         }
4711
4712         class GeneratedBaseInitializer: ConstructorBaseInitializer {
4713                 public GeneratedBaseInitializer (Location loc):
4714                         base (null, loc)
4715                 {
4716                 }
4717         }
4718
4719         public class ConstructorThisInitializer : ConstructorInitializer {
4720                 public ConstructorThisInitializer (ArrayList argument_list, Location l) :
4721                         base (argument_list, l)
4722                 {
4723                 }
4724         }
4725         
4726         public class Constructor : MethodCore, IMethodData, IAnonymousHost {
4727                 public ConstructorBuilder ConstructorBuilder;
4728                 public ConstructorInitializer Initializer;
4729                 ListDictionary declarative_security;
4730                 ArrayList anonymous_methods;
4731
4732                 // <summary>
4733                 //   Modifiers allowed for a constructor.
4734                 // </summary>
4735                 public const int AllowedModifiers =
4736                         Modifiers.PUBLIC |
4737                         Modifiers.PROTECTED |
4738                         Modifiers.INTERNAL |
4739                         Modifiers.STATIC |
4740                         Modifiers.UNSAFE |
4741                         Modifiers.EXTERN |              
4742                         Modifiers.PRIVATE;
4743
4744                 static string[] attribute_targets = new string [] { "method" };
4745
4746                 public Iterator Iterator {
4747                         get { return null; }
4748                 }
4749
4750                 bool has_compliant_args = false;
4751                 //
4752                 // The spec claims that static is not permitted, but
4753                 // my very own code has static constructors.
4754                 //
4755                 public Constructor (DeclSpace parent, string name, int mod, Parameters args,
4756                                     ConstructorInitializer init, Location loc)
4757                         : base (parent, null, null, mod, AllowedModifiers, false,
4758                                 new MemberName (name, loc), null, args)
4759                 {
4760                         Initializer = init;
4761                 }
4762
4763                 public bool HasCompliantArgs {
4764                         get { return has_compliant_args; }
4765                 }
4766
4767                 public override AttributeTargets AttributeTargets {
4768                         get { return AttributeTargets.Constructor; }
4769                 }
4770
4771
4772                 //
4773                 // Returns true if this is a default constructor
4774                 //
4775                 public bool IsDefault ()
4776                 {
4777                         if ((ModFlags & Modifiers.STATIC) != 0)
4778                                 return Parameters.Empty;
4779                         
4780                         return Parameters.Empty &&
4781                                         (Initializer is ConstructorBaseInitializer) &&
4782                                         (Initializer.Arguments == null);
4783                 }
4784
4785                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4786                 {
4787                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4788                                 if (declarative_security == null) {
4789                                         declarative_security = new ListDictionary ();
4790                                 }
4791                                 a.ExtractSecurityPermissionSet (declarative_security);
4792                                 return;
4793                         }
4794
4795                         if (a.IsInternalMethodImplAttribute) {
4796                                 is_external_implementation = true;
4797                         }
4798
4799                         ConstructorBuilder.SetCustomAttribute (cb);
4800                 }
4801
4802                 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
4803                 {
4804                         if (anonymous_methods == null)
4805                                 anonymous_methods = new ArrayList ();
4806                         anonymous_methods.Add (anonymous);
4807                 }
4808
4809                 public bool ResolveMembers ()
4810                 {
4811                         if (anonymous_methods != null) {
4812                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
4813                                         if (!ame.CreateAnonymousHelpers ())
4814                                                 return false;
4815                                 }
4816                         }
4817
4818                         return true;
4819                 }
4820
4821                 protected override bool CheckForDuplications ()
4822                 {
4823                         ArrayList ar = Parent.PartialContainer.InstanceConstructors;
4824                         if (ar != null) {
4825                                 int arLen = ar.Count;
4826                                         
4827                                 for (int i = 0; i < arLen; i++) {
4828                                         Constructor m = (Constructor) ar [i];
4829                                         if (IsDuplicateImplementation (m))
4830                                                 return false;
4831                                 }
4832                         }
4833                         return true;
4834                 }
4835
4836                 protected override bool CheckBase ()
4837                 {
4838                         if ((ModFlags & Modifiers.STATIC) != 0) {
4839                                 if (!Parameters.Empty) {
4840                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
4841                                                 GetSignatureForError ());
4842                                         return false;
4843                                 }
4844
4845                                 // the rest can be ignored
4846                                 return true;
4847                         }
4848
4849                         // Check whether arguments were correct.
4850                         if (!DefineParameters (Parameters))
4851                                 return false;
4852
4853                         if (!CheckForDuplications ())
4854                                 return false;
4855
4856                         if (Parent.PartialContainer.Kind == Kind.Struct) {
4857                                 if (ParameterTypes.Length == 0) {
4858                                         Report.Error (568, Location, 
4859                                                 "Structs cannot contain explicit parameterless constructors");
4860                                         return false;
4861                                 }
4862
4863                                 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4864                                         Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
4865                                         return false;
4866                                 }
4867                         }
4868
4869                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0) {
4870                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4871                         }
4872                         
4873                         return true;
4874                 }
4875                 
4876                 //
4877                 // Creates the ConstructorBuilder
4878                 //
4879                 public override bool Define ()
4880                 {
4881                         if (ConstructorBuilder != null)
4882                                 return true;
4883
4884                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
4885                                                MethodAttributes.SpecialName);
4886                         
4887                         if ((ModFlags & Modifiers.STATIC) != 0) {
4888                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
4889                         } else {
4890                                 ca |= MethodAttributes.HideBySig;
4891
4892                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
4893                                         ca |= MethodAttributes.Public;
4894                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4895                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
4896                                                 ca |= MethodAttributes.FamORAssem;
4897                                         else 
4898                                                 ca |= MethodAttributes.Family;
4899                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4900                                         ca |= MethodAttributes.Assembly;
4901                                 else
4902                                         ca |= MethodAttributes.Private;
4903                         }
4904
4905                         if (!CheckAbstractAndExtern (block != null))
4906                                 return false;
4907                         
4908                         // Check if arguments were correct.
4909                         if (!CheckBase ())
4910                                 return false;
4911
4912                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4913                                 ca, CallingConventions,
4914                                 ParameterTypes);
4915
4916                         if ((ModFlags & Modifiers.UNSAFE) != 0)
4917                                 ConstructorBuilder.InitLocals = false;
4918
4919                         if (Parent.PartialContainer.IsComImport) {
4920                                 if (!IsDefault ()) {
4921                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4922                                                 Parent.GetSignatureForError ());
4923                                         return false;
4924                                 }
4925                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4926                         }
4927                         
4928                         TypeManager.AddMethod (ConstructorBuilder, this);
4929
4930                         return true;
4931                 }
4932
4933                 //
4934                 // Emits the code
4935                 //
4936                 public override void Emit ()
4937                 {
4938                         if (OptAttributes != null)
4939                                 OptAttributes.Emit ();
4940
4941                         EmitContext ec = CreateEmitContext (null, null);
4942
4943                         if (block != null) {
4944                                 // If this is a non-static `struct' constructor and doesn't have any
4945                                 // initializer, it must initialize all of the struct's fields.
4946                                 if ((Parent.PartialContainer.Kind == Kind.Struct) &&
4947                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4948                                         block.AddThisVariable (Parent, Location);
4949
4950                                 if (!block.ResolveMeta (ec, ParameterInfo))
4951                                         block = null;
4952                         }
4953
4954                         if ((ModFlags & Modifiers.STATIC) == 0){
4955                                 if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
4956                                         Initializer = new GeneratedBaseInitializer (Location);
4957
4958
4959                                 //
4960                                 // Spec mandates that Initializers will not have
4961                                 // `this' access
4962                                 //
4963                                 ec.IsStatic = true;
4964                                 if ((Initializer != null) &&
4965                                     !Initializer.Resolve (ConstructorBuilder, block, ec))
4966                                         return;
4967                                 ec.IsStatic = false;
4968                         }
4969
4970                         Parameters.ApplyAttributes (ConstructorBuilder);
4971                         
4972                         SourceMethod source = SourceMethod.Create (
4973                                 Parent, ConstructorBuilder, block);
4974
4975                         //
4976                         // Classes can have base initializers and instance field initializers.
4977                         //
4978                         if (Parent.PartialContainer.Kind == Kind.Class){
4979                                 if ((ModFlags & Modifiers.STATIC) == 0){
4980
4981                                         //
4982                                         // If we use a "this (...)" constructor initializer, then
4983                                         // do not emit field initializers, they are initialized in the other constructor
4984                                         //
4985                                         if (!(Initializer != null && Initializer is ConstructorThisInitializer))
4986                                                 Parent.PartialContainer.EmitFieldInitializers (ec);
4987                                 }
4988                         }
4989
4990                         bool unreachable = false;
4991                         if (block != null) {
4992                                 if (!ec.ResolveTopBlock (null, block, ParameterInfo, this, out unreachable))
4993                                         return;
4994                                 ec.EmitMeta (block);
4995
4996                                 if (block.ScopeInfo != null) {
4997                                         ExpressionStatement init = block.ScopeInfo.GetScopeInitializer (ec);
4998                                         init.EmitStatement (ec);
4999                                 }
5000                         }
5001
5002                         if (Initializer != null) {
5003                                 Initializer.Emit (ec);
5004                         }
5005                         
5006                         if ((ModFlags & Modifiers.STATIC) != 0)
5007                                 Parent.PartialContainer.EmitFieldInitializers (ec);
5008
5009                         if (block != null)
5010                                 ec.EmitResolvedTopBlock (block, unreachable);
5011
5012                         if (source != null)
5013                                 source.CloseMethod ();
5014
5015                         base.Emit ();
5016
5017                         if (declarative_security != null) {
5018                                 foreach (DictionaryEntry de in declarative_security) {
5019                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5020                                 }
5021                         }
5022
5023                         block = null;
5024                 }
5025
5026                 // Is never override
5027                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
5028                 {
5029                         return null;
5030                 }
5031
5032                 public override string GetSignatureForError()
5033                 {
5034                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
5035                 }
5036
5037                 public override string[] ValidAttributeTargets {
5038                         get {
5039                                 return attribute_targets;
5040                         }
5041                 }
5042
5043                 protected override bool VerifyClsCompliance ()
5044                 {
5045                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
5046                                 return false;
5047                         }
5048                         
5049                         if (ParameterInfo.Count > 0) {
5050                                 ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
5051                                 if (al.Count > 3)
5052                                         MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
5053  
5054                                 if (Parent.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
5055                                         foreach (Type param in ParameterTypes) {
5056                                                 if (param.IsArray) {
5057                                                         return true;
5058                                                 }
5059                                         }
5060                                 }
5061                         }
5062                         has_compliant_args = true;
5063                         return true;
5064                 }
5065
5066                 #region IMethodData Members
5067
5068                 public System.Reflection.CallingConventions CallingConventions {
5069                         get {
5070                                 CallingConventions cc = Parameters.CallingConvention;
5071
5072                                 if (Parent.PartialContainer.Kind == Kind.Class)
5073                                         if ((ModFlags & Modifiers.STATIC) == 0)
5074                                                 cc |= CallingConventions.HasThis;
5075
5076                                 // FIXME: How is `ExplicitThis' used in C#?
5077                         
5078                                 return cc;
5079                         }
5080                 }
5081
5082                 public new Location Location {
5083                         get {
5084                                 return base.Location;
5085                         }
5086                 }
5087
5088                 public MemberName MethodName {
5089                         get {
5090                                 return MemberName;
5091                         }
5092                 }
5093
5094                 public Type ReturnType {
5095                         get {
5096                                 return MemberType;
5097                         }
5098                 }
5099
5100                 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
5101                 {
5102                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
5103                         return new EmitContext (this, Parent, Location, ig_, TypeManager.void_type, ModFlags, true);
5104                 }
5105
5106                 public bool IsExcluded()
5107                 {
5108                         return false;
5109                 }
5110
5111                 GenericMethod IMethodData.GenericMethod {
5112                         get {
5113                                 return null;
5114                         }
5115                 }
5116
5117                 #endregion
5118         }
5119
5120         /// <summary>
5121         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
5122         /// </summary>
5123         public interface IMethodData
5124         {
5125                 CallingConventions CallingConventions { get; }
5126                 Location Location { get; }
5127                 MemberName MethodName { get; }
5128                 Type ReturnType { get; }
5129                 GenericMethod GenericMethod { get; }
5130                 Parameters ParameterInfo { get; }
5131
5132                 Iterator Iterator { get; }
5133
5134                 Attributes OptAttributes { get; }
5135                 ToplevelBlock Block { get; set; }
5136
5137                 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5138                 ObsoleteAttribute GetObsoleteAttribute ();
5139                 string GetSignatureForError ();
5140                 bool IsExcluded ();
5141                 bool IsClsComplianceRequired ();
5142                 void SetMemberIsUsed ();
5143         }
5144
5145         //
5146         // Encapsulates most of the Method's state
5147         //
5148         public class MethodData {
5149
5150                 readonly IMethodData method;
5151
5152                 public readonly GenericMethod GenericMethod;
5153
5154                 //
5155                 // Are we implementing an interface ?
5156                 //
5157                 public MethodInfo implementing;
5158
5159                 //
5160                 // Protected data.
5161                 //
5162                 protected InterfaceMemberBase member;
5163                 protected int modifiers;
5164                 protected MethodAttributes flags;
5165                 protected Type declaring_type;
5166                 protected MethodInfo parent_method;
5167
5168                 MethodBuilder builder = null;
5169                 public MethodBuilder MethodBuilder {
5170                         get {
5171                                 return builder;
5172                         }
5173                 }
5174
5175                 public Type DeclaringType {
5176                         get {
5177                                 return declaring_type;
5178                         }
5179                 }
5180
5181                 public MethodData (InterfaceMemberBase member,
5182                                    int modifiers, MethodAttributes flags, IMethodData method)
5183                 {
5184                         this.member = member;
5185                         this.modifiers = modifiers;
5186                         this.flags = flags;
5187
5188                         this.method = method;
5189                 }
5190
5191                 public MethodData (InterfaceMemberBase member, 
5192                                    int modifiers, MethodAttributes flags, 
5193                                    IMethodData method, MethodBuilder builder,
5194                                    GenericMethod generic, MethodInfo parent_method)
5195                         : this (member, modifiers, flags, method)
5196                 {
5197                         this.builder = builder;
5198                         this.GenericMethod = generic;
5199                         this.parent_method = parent_method;
5200                 }
5201
5202                 public bool Define (DeclSpace parent)
5203                 {
5204                         string name = method.MethodName.Basename;
5205                         string method_name = method.MethodName.FullName;
5206
5207                         TypeContainer container = parent.PartialContainer;
5208
5209                         PendingImplementation pending = container.PendingImplementations;
5210                         if (pending != null){
5211                                 if (member is Indexer) // TODO: test it, but it should work without this IF
5212                                         implementing = pending.IsInterfaceIndexer (
5213                                                 member.InterfaceType, method.ReturnType, method.ParameterInfo);
5214                                 else
5215                                         implementing = pending.IsInterfaceMethod (
5216                                                 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
5217
5218                                 if (member.InterfaceType != null){
5219                                         if (implementing == null){
5220                                                 if (member is PropertyBase) {
5221                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
5222                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
5223                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
5224
5225                                                 } else {
5226                                                         Report.Error (539, method.Location,
5227                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
5228                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
5229                                                 }
5230                                                 return false;
5231                                         }
5232                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
5233                                                 Report.SymbolRelatedToPreviousError (implementing);
5234                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5235                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
5236                                                 return false;
5237                                         }
5238
5239                                         method_name = member.InterfaceType.FullName + 
5240                                                 '.' + method_name;
5241                                 } else {
5242                                         if (implementing != null) {
5243                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
5244                                                 if (prop_method == null) {
5245                                                         if (implementing.IsSpecialName) {
5246                                                                 Report.SymbolRelatedToPreviousError (implementing);
5247                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5248                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
5249                                                                         implementing.Name.StartsWith ("get_") ? "get" : "set");
5250                                                                 return false;
5251                                                         }
5252                                                 } else if (implementing.DeclaringType.IsInterface) {
5253                                                         if (!implementing.IsSpecialName) {
5254                                                                 Report.SymbolRelatedToPreviousError (implementing);
5255                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5256                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
5257                                                                 return false;
5258                                                         }
5259                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
5260                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
5261                                                                 Report.SymbolRelatedToPreviousError (implementing);
5262                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5263                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
5264                                                                 return false;
5265                                                         }
5266                                                 }
5267                                         }
5268                                 }
5269                         }
5270
5271                         //
5272                         // For implicit implementations, make sure we are public, for
5273                         // explicit implementations, make sure we are private.
5274                         //
5275                         if (implementing != null){
5276                                 //
5277                                 // Setting null inside this block will trigger a more
5278                                 // verbose error reporting for missing interface implementations
5279                                 //
5280                                 // The "candidate" function has been flagged already
5281                                 // but it wont get cleared
5282                                 //
5283                                 if (member.IsExplicitImpl){
5284                                         if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
5285                                                 Report.SymbolRelatedToPreviousError (implementing);
5286                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5287                                                         method.GetSignatureForError ());
5288                                                 return false;
5289                                         }
5290                                 } else {
5291                                         if (implementing.DeclaringType.IsInterface) {
5292                                                 //
5293                                                 // If this is an interface method implementation,
5294                                                 // check for public accessibility
5295                                                 //
5296                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5297                                                 {
5298                                                         implementing = null;
5299                                                 }
5300                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
5301                                                 // We may never be private.
5302                                                 implementing = null;
5303
5304                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
5305                                                 //
5306                                                 // We may be protected if we're overriding something.
5307                                                 //
5308                                                 implementing = null;
5309                                         }
5310                                 }
5311                                         
5312                                 //
5313                                 // Static is not allowed
5314                                 //
5315                                 if ((modifiers & Modifiers.STATIC) != 0){
5316                                         implementing = null;
5317                                 }
5318                         }
5319                         
5320                         //
5321                         // If implementing is still valid, set flags
5322                         //
5323                         if (implementing != null){
5324                                 //
5325                                 // When implementing interface methods, set NewSlot
5326                                 // unless, we are overwriting a method.
5327                                 //
5328                                 if (implementing.DeclaringType.IsInterface){
5329                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
5330                                                 flags |= MethodAttributes.NewSlot;
5331                                 }
5332                                 flags |=
5333                                         MethodAttributes.Virtual |
5334                                         MethodAttributes.HideBySig;
5335
5336                                 // Set Final unless we're virtual, abstract or already overriding a method.
5337                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
5338                                         flags |= MethodAttributes.Final;
5339                         }
5340
5341                         DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
5342
5343                         if (builder == null)
5344                                 return false;
5345
5346                         if (container.CurrentType != null)
5347                                 declaring_type = container.CurrentType;
5348                         else
5349                                 declaring_type = container.TypeBuilder;
5350
5351                         if ((modifiers & Modifiers.UNSAFE) != 0)
5352                                 builder.InitLocals = false;
5353
5354
5355                         if (implementing != null){
5356                                 //
5357                                 // clear the pending implemntation flag
5358                                 //
5359                                 if (member is Indexer) {
5360                                         pending.ImplementIndexer (
5361                                                 member.InterfaceType, builder, method.ReturnType,
5362                                                 method.ParameterInfo, member.IsExplicitImpl);
5363                                 } else
5364                                         pending.ImplementMethod (
5365                                                 member.InterfaceType, name, method.ReturnType,
5366                                                 method.ParameterInfo, member.IsExplicitImpl);
5367
5368                                 if (member.IsExplicitImpl)
5369                                         container.TypeBuilder.DefineMethodOverride (
5370                                                 builder, implementing);
5371                         }
5372
5373                         TypeManager.AddMethod (builder, method);
5374
5375                         if (GenericMethod != null) {
5376                                 bool is_override = member.IsExplicitImpl |
5377                                         ((modifiers & Modifiers.OVERRIDE) != 0);
5378
5379                                 if (implementing != null)
5380                                         parent_method = implementing;
5381
5382                                 EmitContext ec = method.CreateEmitContext (container, null);
5383                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
5384                                         return false;
5385                         }
5386
5387                         return true;
5388                 }
5389
5390
5391                 /// <summary>
5392                 /// Create the MethodBuilder for the method 
5393                 /// </summary>
5394                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
5395                 {
5396                         if (builder == null) {
5397                                 builder = container.TypeBuilder.DefineMethod (
5398                                         method_name, flags, method.CallingConventions,
5399                                         method.ReturnType, ParameterTypes);
5400                                 return;
5401                         }
5402
5403 #if GMCS_SOURCE && !MS_COMPATIBLE
5404                         builder.SetGenericMethodSignature (
5405                                 flags, method.CallingConventions,
5406                                 method.ReturnType, ParameterTypes);
5407 #endif
5408                 }
5409
5410                 //
5411                 // Emits the code
5412                 // 
5413                 public void Emit (DeclSpace parent)
5414                 {
5415                         ToplevelBlock block = method.Block;
5416
5417                         EmitContext ec;
5418                         if (block != null)
5419                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
5420                         else
5421                                 ec = method.CreateEmitContext (parent, null);
5422
5423                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
5424
5425                         if (GenericMethod != null)
5426                                 GenericMethod.EmitAttributes ();
5427                         
5428                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
5429
5430                         //
5431                         // Handle destructors specially
5432                         //
5433                         // FIXME: This code generates buggy code
5434                         //
5435                         if (member is Destructor)
5436                                 EmitDestructor (ec, block);
5437                         else
5438                                 ec.EmitTopBlock (method, block);
5439
5440                         if (source != null)
5441                                 source.CloseMethod ();
5442                 }
5443
5444                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5445                 {
5446                         ILGenerator ig = ec.ig;
5447                         
5448                         Label finish = ig.DefineLabel ();
5449
5450                         block.SetDestructor ();
5451                         
5452                         ig.BeginExceptionBlock ();
5453                         ec.ReturnLabel = finish;
5454                         ec.HasReturnLabel = true;
5455                         ec.EmitTopBlock (method, block);
5456                         
5457                         // ig.MarkLabel (finish);
5458                         ig.BeginFinallyBlock ();
5459                         
5460                         if (ec.ContainerType.BaseType != null) {
5461                                 Expression member_lookup = Expression.MemberLookup (
5462                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5463                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5464
5465                                 if (member_lookup != null){
5466                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5467                                 
5468                                         ig.Emit (OpCodes.Ldarg_0);
5469                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5470                                 }
5471                         }
5472                         
5473                         ig.EndExceptionBlock ();
5474                         //ig.MarkLabel (ec.ReturnLabel);
5475                         ig.Emit (OpCodes.Ret);
5476                 }
5477         }
5478
5479         // TODO: Should derive from MethodCore
5480         public class Destructor : Method {
5481
5482                 static string[] attribute_targets = new string [] { "method" };
5483
5484                 public Destructor (DeclSpace parent, Expression return_type, int mod,
5485                                    string name, Parameters parameters, Attributes attrs,
5486                                    Location l)
5487                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5488                                 parameters, attrs)
5489                 { }
5490
5491                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5492                 {
5493                         if (a.Type == TypeManager.conditional_attribute_type) {
5494                                 Error_ConditionalAttributeIsNotValid ();
5495                                 return;
5496                         }
5497
5498                         base.ApplyAttributeBuilder (a, cb);
5499                 }
5500
5501                 public override string GetSignatureForError ()
5502                 {
5503                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5504                 }
5505
5506                 public override string[] ValidAttributeTargets {
5507                         get {
5508                                 return attribute_targets;
5509                         }
5510                 }
5511         }
5512         
5513         abstract public class MemberBase : MemberCore {
5514                 public Expression Type;
5515                 public readonly DeclSpace ds;
5516                 public readonly GenericMethod GenericMethod;
5517
5518                 //
5519                 // The type of this property / indexer / event
5520                 //
5521                 protected Type member_type;
5522                 public Type MemberType {
5523                         get {
5524                                 if (member_type == null && Type != null) {
5525                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5526                                         Type = Type.ResolveAsTypeTerminal (rc, false);
5527                                         if (Type != null) {
5528                                                 member_type = Type.Type;
5529                                         }
5530                                 }
5531                                 return member_type;
5532                         }
5533                 }
5534
5535                 //
5536                 // The constructor is only exposed to our children
5537                 //
5538                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5539                                       Expression type, int mod, int allowed_mod, int def_mod,
5540                                       MemberName name, Attributes attrs)
5541                         : base (parent, name, attrs)
5542                 {
5543                         this.ds = generic != null ? generic : (DeclSpace) parent;
5544                         Type = type;
5545                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5546                         GenericMethod = generic;
5547                         if (GenericMethod != null)
5548                                 GenericMethod.ModFlags = ModFlags;
5549                 }
5550
5551                 protected virtual bool CheckBase ()
5552                 {
5553                         if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.PartialContainer.Kind == Kind.Struct) {
5554                                 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5555                                 return false;
5556                         }
5557    
5558                         if (Report.WarningLevel >= 4 &&
5559                             ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5560                             ((ModFlags & Modifiers.PROTECTED) != 0) &&
5561                             ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5562                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5563                         }
5564                                 return true;
5565                 }
5566
5567                 protected virtual bool DoDefine ()
5568                 {
5569                         if (MemberType == null)
5570                                 return false;
5571
5572                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5573                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5574                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5575                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5576                                         return false;
5577                         }
5578                         
5579                         // verify accessibility
5580                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5581                                 Report.SymbolRelatedToPreviousError (MemberType);
5582                                 if (this is Property)
5583                                         Report.Error (53, Location,
5584                                                       "Inconsistent accessibility: property type `" +
5585                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5586                                                       "accessible than property `" + GetSignatureForError () + "'");
5587                                 else if (this is Indexer)
5588                                         Report.Error (54, Location,
5589                                                       "Inconsistent accessibility: indexer return type `" +
5590                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5591                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5592                                 else if (this is MethodCore) {
5593                                         if (this is Operator)
5594                                                 Report.Error (56, Location,
5595                                                               "Inconsistent accessibility: return type `" +
5596                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5597                                                               "accessible than operator `" + GetSignatureForError () + "'");
5598                                         else
5599                                                 Report.Error (50, Location,
5600                                                               "Inconsistent accessibility: return type `" +
5601                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5602                                                               "accessible than method `" + GetSignatureForError () + "'");
5603                                 } else {
5604                                         Report.Error (52, Location,
5605                                                       "Inconsistent accessibility: field type `" +
5606                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5607                                                       "accessible than field `" + GetSignatureForError () + "'");
5608                                 }
5609                                 return false;
5610                         }
5611
5612                         return true;
5613                 }
5614
5615                 protected bool IsTypePermitted ()
5616                 {
5617                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5618                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5619                                 return false;
5620                         }
5621                         return true;
5622                 }
5623         }
5624
5625         //
5626         // Abstract class for all fields
5627         //
5628         abstract public class FieldBase : MemberBase {
5629                 public FieldBuilder FieldBuilder;
5630                 public Status status;
5631                 protected Expression initializer;
5632
5633                 [Flags]
5634                 public enum Status : byte {
5635                         HAS_OFFSET = 4          // Used by FieldMember.
5636                 }
5637
5638                 static readonly string[] attribute_targets = new string [] { "field" };
5639
5640                 protected FieldBase (DeclSpace parent, Expression type, int mod,
5641                                      int allowed_mod, MemberName name, Attributes attrs)
5642                         : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE,
5643                                 name, attrs)
5644                 {
5645                         if ((mod & Modifiers.ABSTRACT) != 0)
5646                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5647                 }
5648
5649                 public override AttributeTargets AttributeTargets {
5650                         get {
5651                                 return AttributeTargets.Field;
5652                         }
5653                 }
5654
5655                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5656                 {
5657                         if (a.Type == TypeManager.field_offset_attribute_type) {
5658                                 status |= Status.HAS_OFFSET;
5659
5660                                 if (!Parent.PartialContainer.HasExplicitLayout) {
5661                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5662                                         return;
5663                                 }
5664
5665                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5666                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5667                                         return;
5668                                 }
5669                         }
5670
5671 #if NET_2_0
5672                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5673                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5674                                 return;
5675                         }
5676 #endif
5677
5678                         if (a.Type == TypeManager.marshal_as_attr_type) {
5679                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5680                                 if (marshal != null) {
5681                                         FieldBuilder.SetMarshal (marshal);
5682                                 }
5683                                 return;
5684                         }
5685
5686                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5687                                 a.Error_InvalidSecurityParent ();
5688                                 return;
5689                         }
5690
5691                         FieldBuilder.SetCustomAttribute (cb);
5692                 }
5693
5694                 protected override bool CheckBase ()
5695                 {
5696                         if (!base.CheckBase ())
5697                                 return false;
5698  
5699                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
5700                         if (conflict_symbol == null) {
5701                                 if ((ModFlags & Modifiers.NEW) != 0) {
5702                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5703                                 }
5704                                 return true;
5705                         }
5706  
5707                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5708                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5709                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5710                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5711                         }
5712  
5713                         return true;
5714                 }
5715
5716                 public override bool Define()
5717                 {
5718                         if (MemberType == null || Type == null)
5719                                 return false;
5720
5721                         if (TypeManager.IsGenericParameter (MemberType))
5722                                 return true;
5723
5724                         if (MemberType == TypeManager.void_type) {
5725                                 // TODO: wrong location
5726                                 Expression.Error_VoidInvalidInTheContext (Location);
5727                                 return false;
5728                         }
5729
5730                         if (MemberType.IsSealed && MemberType.IsAbstract) {
5731                                 Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType);
5732                                 return false;
5733                         }
5734
5735                         if (!CheckBase ())
5736                                 return false;
5737                         
5738                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5739                                 Report.Error (52, Location,
5740                                         "Inconsistent accessibility: field type `" +
5741                                         TypeManager.CSharpName (MemberType) + "' is less " +
5742                                         "accessible than field `" + GetSignatureForError () + "'");
5743                                 return false;
5744                         }
5745
5746                         if (!IsTypePermitted ())
5747                                 return false;
5748
5749                         return true;
5750                 }
5751
5752                 //
5753                 //   Represents header string for documentation comment.
5754                 //
5755                 public override string DocCommentHeader {
5756                         get { return "F:"; }
5757                 }
5758
5759                 public override void Emit ()
5760                 {
5761 #if GMCS_SOURCE
5762                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0) {
5763                                 FieldBuilder.SetCustomAttribute (TypeManager.compiler_generated_attr);
5764                         }
5765 #endif
5766
5767                         if (OptAttributes != null) {
5768                                 OptAttributes.Emit ();
5769                         }
5770
5771                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && Parent.PartialContainer.HasExplicitLayout) {
5772                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5773                         }
5774
5775                         base.Emit ();
5776                 }
5777
5778                 public static void Error_VariableOfStaticClass (Location loc, string variable_name, Type static_class)
5779                 {
5780                         Report.SymbolRelatedToPreviousError (static_class);
5781                         Report.Error (723, loc, "`{0}': cannot declare variables of static types",
5782                                 variable_name);
5783                 }
5784
5785                 public Expression Initializer {
5786                         set {
5787                                 if (value != null) {
5788                                         this.initializer = value;
5789                                 }
5790                         }
5791                 }
5792
5793                 protected virtual bool IsFieldClsCompliant {
5794                         get {
5795                                 if (FieldBuilder == null)
5796                                         return true;
5797
5798                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5799                         }
5800                 }
5801
5802                 public override string[] ValidAttributeTargets 
5803                 {
5804                         get {
5805                                 return attribute_targets;
5806                         }
5807                 }
5808
5809                 protected override bool VerifyClsCompliance ()
5810                 {
5811                         if (!base.VerifyClsCompliance ())
5812                                 return false;
5813
5814                         if (!IsFieldClsCompliant) {
5815                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5816                         }
5817                         return true;
5818                 }
5819
5820                 public void SetAssigned ()
5821                 {
5822                         caching_flags |= Flags.IsAssigned;
5823                 }
5824         }
5825
5826         interface IFixedBuffer
5827         {
5828                 FieldInfo Element { get; }
5829                 Type ElementType { get; }
5830         }
5831
5832         public class FixedFieldExternal: IFixedBuffer
5833         {
5834                 FieldInfo element_field;
5835
5836                 public FixedFieldExternal (FieldInfo fi)
5837                 {
5838                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5839                 }
5840
5841                 #region IFixedField Members
5842
5843                 public FieldInfo Element {
5844                         get {
5845                                 return element_field;
5846                         }
5847                 }
5848
5849                 public Type ElementType {
5850                         get {
5851                                 return element_field.FieldType;
5852                         }
5853                 }
5854
5855                 #endregion
5856         }
5857
5858         /// <summary>
5859         /// Fixed buffer implementation
5860         /// </summary>
5861         public class FixedField : FieldBase, IFixedBuffer
5862         {
5863                 public const string FixedElementName = "FixedElementField";
5864                 static int GlobalCounter = 0;
5865                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5866                 static FieldInfo[] fi;
5867
5868                 TypeBuilder fixed_buffer_type;
5869                 FieldBuilder element;
5870                 Expression size_expr;
5871                 int buffer_size;
5872
5873                 const int AllowedModifiers =
5874                         Modifiers.NEW |
5875                         Modifiers.PUBLIC |
5876                         Modifiers.PROTECTED |
5877                         Modifiers.INTERNAL |
5878                         Modifiers.PRIVATE;
5879
5880                 public FixedField (DeclSpace parent, Expression type, int mod, string name,
5881                         Expression size_expr, Attributes attrs, Location loc):
5882                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5883                 {
5884                         if (RootContext.Version == LanguageVersion.ISO_1)
5885                                 Report.FeatureIsNotISO1 (loc, "fixed size buffers");
5886
5887                         if ((mod & Modifiers.VOLATILE) != 0)
5888                                 Modifiers.Error_InvalidModifier (loc, Modifiers.Name (Modifiers.VOLATILE));
5889
5890                         this.size_expr = size_expr;
5891                 }
5892
5893                 public override bool Define()
5894                 {
5895 #if !NET_2_0
5896                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5897                                 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5898 #endif
5899
5900                         if (Parent.PartialContainer.Kind != Kind.Struct) {
5901                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5902                                         GetSignatureForError ());
5903                         }
5904
5905                         if (!Parent.IsInUnsafeScope)
5906                                 Expression.UnsafeError (Location);
5907
5908                         if (!base.Define ())
5909                                 return false;
5910
5911                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5912                                 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",
5913                                         GetSignatureForError ());
5914                                 return false;
5915                         }
5916
5917                         EmitContext ec = new EmitContext (this, Parent, Location, null, TypeManager.void_type, ModFlags);
5918                         Constant c = size_expr.ResolveAsConstant (ec, this);
5919                         if (c == null)
5920                                 return false;
5921
5922                         IntConstant buffer_size_const = c.ImplicitConversionRequired (TypeManager.int32_type, Location) as IntConstant;
5923                         if (buffer_size_const == null)
5924                                 return false;
5925
5926                         buffer_size = buffer_size_const.Value;
5927
5928                         if (buffer_size <= 0) {
5929                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5930                                 return false;
5931                         }
5932
5933                         int type_size = Expression.GetTypeSize (MemberType);
5934
5935                         if (buffer_size > int.MaxValue / type_size) {
5936                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5937                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5938                                 return false;
5939                         }
5940
5941                         buffer_size *= type_size;
5942
5943                         // Define nested
5944                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5945
5946                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5947                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5948                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5949                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5950
5951                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5952                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5953
5954                         return true;
5955                 }
5956
5957                 public override void Emit()
5958                 {
5959                         if (fi == null)
5960                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5961
5962                         object[] fi_val = new object[1];
5963                         fi_val [0] = buffer_size;
5964
5965                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5966                                 ctor_args, fi, fi_val);
5967                         fixed_buffer_type.SetCustomAttribute (cab);
5968
5969 #if NET_2_0
5970                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5971                         FieldBuilder.SetCustomAttribute (cab);
5972 #endif
5973                         base.Emit ();
5974                 }
5975
5976                 protected override bool IsFieldClsCompliant {
5977                         get {
5978                                 return false;
5979                         }
5980                 }
5981
5982                 #region IFixedField Members
5983
5984                 public FieldInfo Element {
5985                         get {
5986                                 return element;
5987                         }
5988                 }
5989
5990                 public Type ElementType {
5991                         get {
5992                                 return MemberType;
5993                         }
5994                 }
5995
5996                 #endregion
5997         }
5998
5999         //
6000         // The Field class is used to represents class/struct fields during parsing.
6001         //
6002         public class Field : FieldBase {
6003                 // <summary>
6004                 //   Modifiers allowed in a class declaration
6005                 // </summary>
6006                 const int AllowedModifiers =
6007                         Modifiers.NEW |
6008                         Modifiers.PUBLIC |
6009                         Modifiers.PROTECTED |
6010                         Modifiers.INTERNAL |
6011                         Modifiers.PRIVATE |
6012                         Modifiers.STATIC |
6013                         Modifiers.VOLATILE |
6014                         Modifiers.UNSAFE |
6015                         Modifiers.READONLY;
6016
6017                 public Field (DeclSpace parent, Expression type, int mod, string name,
6018                               Attributes attrs, Location loc)
6019                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
6020                                 attrs)
6021                 {
6022                 }
6023
6024                 public override bool Define ()
6025                 {
6026                         if (!base.Define ())
6027                                 return false;
6028
6029                         if ((ModFlags & Modifiers.VOLATILE) != 0){
6030                                 if (!MemberType.IsClass){
6031                                         Type vt = MemberType;
6032                                         
6033                                         if (TypeManager.IsEnumType (vt))
6034                                                 vt = TypeManager.EnumToUnderlying (MemberType);
6035
6036                                         if (!((vt == TypeManager.bool_type) ||
6037                                               (vt == TypeManager.sbyte_type) ||
6038                                               (vt == TypeManager.byte_type) ||
6039                                               (vt == TypeManager.short_type) ||
6040                                               (vt == TypeManager.ushort_type) ||
6041                                               (vt == TypeManager.int32_type) ||
6042                                               (vt == TypeManager.uint32_type) ||    
6043                                               (vt == TypeManager.char_type) ||
6044                                               (vt == TypeManager.float_type) ||
6045                                               (!vt.IsValueType))){
6046                                                 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
6047                                                         GetSignatureForError (), TypeManager.CSharpName (vt));
6048                                                 return false;
6049                                         }
6050                                 }
6051
6052                                 if ((ModFlags & Modifiers.READONLY) != 0){
6053                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
6054                                                 GetSignatureForError ());
6055                                         return false;
6056                                 }
6057                         }
6058
6059                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
6060
6061                         if (Parent.PartialContainer.Kind == Kind.Struct && 
6062                             ((fa & FieldAttributes.Static) == 0) &&
6063                             MemberType == Parent.TypeBuilder &&
6064                             !TypeManager.IsBuiltinType (MemberType)){
6065                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
6066                                               "' causes a cycle in the structure layout");
6067                                 return false;
6068                         }
6069
6070                         try {
6071                                 FieldBuilder = Parent.TypeBuilder.DefineField (
6072                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
6073
6074                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
6075                         }
6076                         catch (ArgumentException) {
6077                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
6078                                 return false;
6079                         }
6080
6081                         if (initializer != null)
6082                                 Parent.PartialContainer.RegisterFieldForInitialization (this,
6083                                         new FieldInitializer (FieldBuilder, initializer, Parent));
6084
6085                         return true;
6086                 }
6087
6088                 protected override bool VerifyClsCompliance ()
6089                 {
6090                         if (!base.VerifyClsCompliance ())
6091                                 return false;
6092
6093                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
6094                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
6095                         }
6096
6097                         return true;
6098                 }
6099         }
6100
6101         //
6102         // `set' and `get' accessors are represented with an Accessor.
6103         // 
6104         public class Accessor : IAnonymousHost {
6105                 //
6106                 // Null if the accessor is empty, or a Block if not
6107                 //
6108                 public const int AllowedModifiers = 
6109                         Modifiers.PUBLIC |
6110                         Modifiers.PROTECTED |
6111                         Modifiers.INTERNAL |
6112                         Modifiers.PRIVATE;
6113                 
6114                 public ToplevelBlock Block;
6115                 public Attributes Attributes;
6116                 public Location Location;
6117                 public int ModFlags;
6118                 public bool Yields;
6119                 public ArrayList AnonymousMethods;
6120                 
6121                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
6122                 {
6123                         Block = b;
6124                         Attributes = attrs;
6125                         Location = loc;
6126                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
6127                 }
6128
6129                 public void SetYields ()
6130                 {
6131                         Yields = true;
6132                 }
6133
6134                 public void AddAnonymousMethod (AnonymousMethodExpression ame)
6135                 {
6136                         if (AnonymousMethods == null)
6137                                 AnonymousMethods = new ArrayList ();
6138                         AnonymousMethods.Add (ame);
6139                 }
6140         }
6141
6142         // Ooouh Martin, templates are missing here.
6143         // When it will be possible move here a lot of child code and template method type.
6144         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
6145                 protected MethodData method_data;
6146                 protected ToplevelBlock block;
6147                 protected ListDictionary declarative_security;
6148
6149                 // The accessor are created event if they are not wanted.
6150                 // But we need them because their names are reserved.
6151                 // Field says whether accessor will be emited or not
6152                 public readonly bool IsDummy;
6153
6154                 protected readonly string prefix;
6155
6156                 ReturnParameter return_attributes;
6157
6158                 public AbstractPropertyEventMethod (PropertyBasedMember member, string prefix)
6159                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
6160                 {
6161                         this.prefix = prefix;
6162                         IsDummy = true;
6163                 }
6164
6165                 public AbstractPropertyEventMethod (InterfaceMemberBase member, Accessor accessor,
6166                                                     string prefix)
6167                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
6168                                 accessor.Attributes)
6169                 {
6170                         this.prefix = prefix;
6171                         this.block = accessor.Block;
6172                 }
6173
6174                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
6175                 {
6176                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
6177                 }
6178
6179                 public void UpdateName (InterfaceMemberBase member)
6180                 {
6181                         SetMemberName (SetupName (prefix, member, Location));
6182                 }
6183
6184                 #region IMethodData Members
6185
6186                 public abstract Iterator Iterator {
6187                         get;
6188                 }
6189
6190                 public ToplevelBlock Block {
6191                         get {
6192                                 return block;
6193                         }
6194
6195                         set {
6196                                 block = value;
6197                         }
6198                 }
6199
6200                 public CallingConventions CallingConventions {
6201                         get {
6202                                 return CallingConventions.Standard;
6203                         }
6204                 }
6205
6206                 public bool IsExcluded ()
6207                 {
6208                         return false;
6209                 }
6210
6211                 GenericMethod IMethodData.GenericMethod {
6212                         get {
6213                                 return null;
6214                         }
6215                 }
6216
6217                 public MemberName MethodName {
6218                         get {
6219                                 return MemberName;
6220                         }
6221                 }
6222
6223                 public Type[] ParameterTypes { 
6224                         get {
6225                                 return ParameterInfo.Types;
6226                         }
6227                 }
6228
6229                 public abstract Parameters ParameterInfo { get ; }
6230                 public abstract Type ReturnType { get; }
6231                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
6232
6233                 #endregion
6234
6235                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
6236                 {
6237                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
6238                                         a.Type == TypeManager.conditional_attribute_type) {
6239                                 Report.Error (1667, a.Location,
6240                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6241                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
6242                                 return;
6243                         }
6244
6245                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
6246                                 if (declarative_security == null)
6247                                         declarative_security = new ListDictionary ();
6248                                 a.ExtractSecurityPermissionSet (declarative_security);
6249                                 return;
6250                         }
6251
6252                         if (a.Target == AttributeTargets.Method) {
6253                                 method_data.MethodBuilder.SetCustomAttribute (cb);
6254                                 return;
6255                         }
6256
6257                         if (a.Target == AttributeTargets.ReturnValue) {
6258                                 if (return_attributes == null)
6259                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6260
6261                                 return_attributes.ApplyAttributeBuilder (a, cb);
6262                                 return;
6263                         }
6264
6265                         ApplyToExtraTarget (a, cb);
6266                 }
6267
6268                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
6269                 {
6270                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
6271                 }
6272
6273                 // It is not supported for the accessors
6274                 public sealed override bool Define()
6275                 {
6276                         throw new NotSupportedException ();
6277                 }
6278
6279                 public void Emit (DeclSpace parent)
6280                 {
6281                         EmitMethod (parent);
6282
6283 #if GMCS_SOURCE                 
6284                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0)
6285                                 method_data.MethodBuilder.SetCustomAttribute (TypeManager.compiler_generated_attr);
6286 #endif                  
6287                         if (OptAttributes != null)
6288                                 OptAttributes.Emit ();
6289
6290                         if (declarative_security != null) {
6291                                 foreach (DictionaryEntry de in declarative_security) {
6292                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
6293                                 }
6294                         }
6295
6296                         block = null;
6297                 }
6298
6299                 protected virtual void EmitMethod (DeclSpace parent)
6300                 {
6301                         method_data.Emit (parent);
6302                 }
6303
6304                 public override bool IsClsComplianceRequired()
6305                 {
6306                         return false;
6307                 }
6308
6309                 public bool IsDuplicateImplementation (MethodCore method)
6310                 {
6311                         if (!MemberName.Equals (method.MemberName))
6312                                 return false;
6313
6314                         Type[] param_types = method.ParameterTypes;
6315
6316                         if (param_types == null || param_types.Length != ParameterTypes.Length)
6317                                 return false;
6318
6319                         for (int i = 0; i < param_types.Length; i++)
6320                                 if (param_types [i] != ParameterTypes [i])
6321                                         return false;
6322
6323                         Report.SymbolRelatedToPreviousError (method);
6324                         Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
6325                         return true;
6326                 }
6327
6328                 public override bool IsUsed
6329                 {
6330                         get {
6331                                 if (IsDummy)
6332                                         return false;
6333
6334                                 return base.IsUsed;
6335                         }
6336                 }
6337
6338                 public new Location Location { 
6339                         get {
6340                                 return base.Location;
6341                         }
6342                 }
6343
6344                 public virtual bool ResolveMembers ()
6345                 {
6346                         return true;
6347                 }
6348
6349                 //
6350                 //   Represents header string for documentation comment.
6351                 //
6352                 public override string DocCommentHeader {
6353                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6354                 }
6355
6356         }
6357
6358         //
6359         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6360         // their common bits.
6361         //
6362         abstract public class PropertyBase : PropertyBasedMember {
6363
6364                 public class GetMethod : PropertyMethod
6365                 {
6366                         static string[] attribute_targets = new string [] { "method", "return" };
6367
6368                         public GetMethod (PropertyBase method):
6369                                 base (method, "get_")
6370                         {
6371                         }
6372
6373                         public GetMethod (PropertyBase method, Accessor accessor):
6374                                 base (method, accessor, "get_")
6375                         {
6376                         }
6377
6378                         public override MethodBuilder Define (DeclSpace parent)
6379                         {
6380                                 if (!CheckForDuplications ())
6381                                         return null;
6382
6383                                 if (IsDummy)
6384                                         return null;
6385                                 
6386                                 base.Define (parent);
6387                                 
6388                                 method_data = new MethodData (method, ModFlags, flags, this);
6389
6390                                 if (!method_data.Define (parent))
6391                                         return null;
6392
6393                                 return method_data.MethodBuilder;
6394                         }
6395
6396                         public override Type ReturnType {
6397                                 get {
6398                                         return method.MemberType;
6399                                 }
6400                         }
6401
6402                         public override Parameters ParameterInfo {
6403                                 get {
6404                                         return Parameters.EmptyReadOnlyParameters;
6405                                 }
6406                         }
6407
6408                         public override string[] ValidAttributeTargets {
6409                                 get {
6410                                         return attribute_targets;
6411                                 }
6412                         }
6413                 }
6414
6415                 public class SetMethod : PropertyMethod {
6416
6417                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6418                         ImplicitParameter param_attr;
6419                         protected Parameters parameters;
6420
6421                         public SetMethod (PropertyBase method):
6422                                 base (method, "set_")
6423                         {
6424                         }
6425
6426                         public SetMethod (PropertyBase method, Accessor accessor):
6427                                 base (method, accessor, "set_")
6428                         {
6429                         }
6430
6431                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6432                         {
6433                                 if (a.Target == AttributeTargets.Parameter) {
6434                                         if (param_attr == null)
6435                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6436
6437                                         param_attr.ApplyAttributeBuilder (a, cb);
6438                                         return;
6439                                 }
6440
6441                                 base.ApplyAttributeBuilder (a, cb);
6442                         }
6443
6444                         public override Parameters ParameterInfo {
6445                                 get {
6446                                         if (parameters == null)
6447                                                 DefineParameters ();
6448                                         return parameters;
6449                                 }
6450                         }
6451
6452                         protected virtual void DefineParameters ()
6453                         {
6454                                 parameters = Parameters.CreateFullyResolved (
6455                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location));
6456                         }
6457
6458                         public override MethodBuilder Define (DeclSpace parent)
6459                         {
6460                                 if (!CheckForDuplications ())
6461                                         return null;
6462                                 
6463                                 if (IsDummy)
6464                                         return null;
6465
6466                                 base.Define (parent);
6467
6468                                 method_data = new MethodData (method, ModFlags, flags, this);
6469
6470                                 if (!method_data.Define (parent))
6471                                         return null;
6472
6473                                 return method_data.MethodBuilder;
6474                         }
6475
6476                         public override Type ReturnType {
6477                                 get {
6478                                         return TypeManager.void_type;
6479                                 }
6480                         }
6481
6482                         public override string[] ValidAttributeTargets {
6483                                 get {
6484                                         return attribute_targets;
6485                                 }
6486                         }
6487                 }
6488
6489                 static string[] attribute_targets = new string [] { "property" };
6490
6491                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6492                 {
6493                         protected readonly PropertyBase method;
6494                         protected MethodAttributes flags;
6495                         Iterator iterator;
6496                         ArrayList anonymous_methods;
6497                         bool yields;
6498
6499                         public PropertyMethod (PropertyBase method, string prefix)
6500                                 : base (method, prefix)
6501                         {
6502                                 this.method = method;
6503                         }
6504
6505                         public PropertyMethod (PropertyBase method, Accessor accessor,
6506                                                string prefix)
6507                                 : base (method, accessor, prefix)
6508                         {
6509                                 this.method = method;
6510                                 this.ModFlags = accessor.ModFlags;
6511                                 yields = accessor.Yields;
6512                                 anonymous_methods = accessor.AnonymousMethods;
6513
6514                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6515                                         Report.FeatureIsNotISO1 (Location, "access modifiers on properties");
6516                                 }
6517                         }
6518
6519                         public override Iterator Iterator {
6520                                 get { return iterator; }
6521                         }
6522
6523                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6524                         {
6525                                 if (a.IsInternalMethodImplAttribute) {
6526                                         method.is_external_implementation = true;
6527                                 }
6528
6529                                 base.ApplyAttributeBuilder (a, cb);
6530                         }
6531
6532                         public override AttributeTargets AttributeTargets {
6533                                 get {
6534                                         return AttributeTargets.Method;
6535                                 }
6536                         }
6537
6538                         public override bool IsClsComplianceRequired ()
6539                         {
6540                                 return method.IsClsComplianceRequired ();
6541                         }
6542
6543                         public override bool ResolveMembers ()
6544                         {
6545                                 if (yields) {
6546                                         iterator = Iterator.CreateIterator (this, Parent, null, ModFlags);
6547                                         if (iterator == null)
6548                                                 return false;
6549                                 }
6550
6551                                 if (anonymous_methods != null) {
6552                                         foreach (AnonymousMethodExpression ame in anonymous_methods) {
6553                                                 if (!ame.CreateAnonymousHelpers ())
6554                                                         return false;
6555                                         }
6556                                 }
6557
6558                                 return true;
6559                         }
6560
6561                         public virtual MethodBuilder Define (DeclSpace parent)
6562                         {
6563                                 TypeContainer container = parent.PartialContainer;
6564
6565                                 //
6566                                 // Check for custom access modifier
6567                                 //
6568                                 if ((ModFlags & Modifiers.Accessibility) == 0) {
6569                                         ModFlags |= method.ModFlags;
6570                                         flags = method.flags;
6571                                 } else {
6572                                         if (container.Kind == Kind.Interface)
6573                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6574                                                         GetSignatureForError ());
6575
6576                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6577                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6578                                         }
6579
6580                                         CheckModifiers (ModFlags);
6581                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6582                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6583                                         flags = Modifiers.MethodAttr (ModFlags);
6584                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6585                                 }
6586
6587                                 CheckAbstractAndExtern (block != null);
6588                                 return null;
6589                         }
6590
6591                         public bool HasCustomAccessModifier
6592                         {
6593                                 get {
6594                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6595                                 }
6596                         }
6597
6598                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6599                         {
6600                                 return new EmitContext (method,
6601                                         ds, method.ds, method.Location, ig, ReturnType,
6602                                         method.ModFlags, false);
6603                         }
6604
6605                         public override ObsoleteAttribute GetObsoleteAttribute ()
6606                         {
6607                                 return method.GetObsoleteAttribute ();
6608                         }
6609
6610                         public override string GetSignatureForError()
6611                         {
6612                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6613                         }
6614                         
6615                         void CheckModifiers (int modflags)
6616                         {
6617                                 modflags &= Modifiers.Accessibility;
6618                                 int flags = 0;
6619                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6620
6621                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6622                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6623                                 }
6624                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6625                                         if ((mflags & Modifiers.INTERNAL) != 0)
6626                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6627
6628                                         flags |= Modifiers.PRIVATE;
6629                                 }
6630                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6631                                         flags |= Modifiers.PRIVATE;
6632
6633                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6634                                         Report.Error (273, Location,
6635                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6636                                                 GetSignatureForError (), method.GetSignatureForError ());
6637                                 }
6638                         }
6639
6640                         public override bool MarkForDuplicationCheck ()
6641                         {
6642                                 caching_flags |= Flags.TestMethodDuplication;
6643                                 return true;
6644                         }
6645
6646                         protected bool CheckForDuplications () 
6647                         {
6648                                 if ((caching_flags & Flags.TestMethodDuplication) == 0)
6649                                         return true;
6650                                 
6651                                 ArrayList ar = Parent.PartialContainer.Methods;
6652                                 if (ar != null) {
6653                                         int arLen = ar.Count;
6654                                         
6655                                         for (int i = 0; i < arLen; i++) {
6656                                                 Method m = (Method) ar [i];
6657                                                 if (IsDuplicateImplementation (m))
6658                                                         return false;
6659                                         }
6660                                 }
6661
6662                                 return true;
6663                         }
6664                 }
6665
6666                 public PropertyMethod Get, Set;
6667                 public PropertyBuilder PropertyBuilder;
6668                 public MethodBuilder GetBuilder, SetBuilder;
6669
6670                 protected bool define_set_first = false;
6671
6672                 public PropertyBase (DeclSpace parent, Expression type, int mod_flags,
6673                                      int allowed_mod, bool is_iface, MemberName name,
6674                                      Attributes attrs, bool define_set_first)
6675                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,     attrs)
6676                 {
6677                          this.define_set_first = define_set_first;
6678                 }
6679
6680                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6681                 {
6682                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6683                                 a.Error_InvalidSecurityParent ();
6684                                 return;
6685                         }
6686
6687                         PropertyBuilder.SetCustomAttribute (cb);
6688                 }
6689
6690                 public override AttributeTargets AttributeTargets {
6691                         get {
6692                                 return AttributeTargets.Property;
6693                         }
6694                 }
6695
6696                 public override bool Define ()
6697                 {
6698                         if (!DoDefine ())
6699                                 return false;
6700
6701                         if (!IsTypePermitted ())
6702                                 return false;
6703
6704                         return true;
6705                 }
6706
6707                 protected override bool DoDefine ()
6708                 {
6709                         if (!base.DoDefine ())
6710                                 return false;
6711
6712                         //
6713                         // Accessors modifiers check
6714                         //
6715                         if ((Get.ModFlags & Modifiers.Accessibility) != 0 &&
6716                                 (Set.ModFlags & Modifiers.Accessibility) != 0) {
6717                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6718                                                 GetSignatureForError ());
6719                                 return false;
6720                         }
6721
6722                         if ((Get.IsDummy || Set.IsDummy)
6723                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6724                                 Report.Error (276, Location, 
6725                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6726                                         GetSignatureForError ());
6727                                 return false;
6728                         }
6729
6730 #if MS_COMPATIBLE
6731                         if (MemberType.IsGenericParameter)
6732                                 return true;
6733 #endif
6734
6735                         if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
6736                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6737                                 return false;
6738                         }
6739
6740                         return true;
6741                 }
6742
6743                 bool DefineGet ()
6744                 {
6745                         GetBuilder = Get.Define (Parent);
6746                         return (Get.IsDummy) ? true : GetBuilder != null;
6747                 }
6748
6749                 bool DefineSet (bool define)
6750                 {
6751                         if (!define)
6752                                 return true;
6753
6754                         SetBuilder = Set.Define (Parent);
6755                         return (Set.IsDummy) ? true : SetBuilder != null;
6756                 }
6757
6758                 protected bool DefineAccessors ()
6759                 {
6760                         return DefineSet (define_set_first) &&
6761                                 DefineGet () &&
6762                                 DefineSet (!define_set_first);
6763                 }
6764
6765                 protected abstract PropertyInfo ResolveBaseProperty ();
6766
6767                 // TODO: rename to Resolve......
6768                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6769                 {
6770                         PropertyInfo base_property = ResolveBaseProperty ();
6771                         if (base_property == null)
6772                                 return null;
6773   
6774                         base_ret_type = base_property.PropertyType;
6775                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6776                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6777                         MethodAttributes get_accessor_access, set_accessor_access;
6778
6779                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6780                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6781                                         Report.SymbolRelatedToPreviousError (base_property);
6782                                         Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6783                                 }
6784
6785                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6786                                         Report.SymbolRelatedToPreviousError (base_property);
6787                                         Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6788                                 }
6789                         }
6790                         
6791                         //
6792                         // Check base class accessors access
6793                         //
6794
6795                         // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6796                         get_accessor_access = set_accessor_access = 0;
6797                         if ((ModFlags & Modifiers.NEW) == 0) {
6798                                 if (get_accessor != null) {
6799                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6800                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6801
6802                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6803                                                 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access,  ".get");
6804                                 }
6805
6806                                 if (set_accessor != null)  {
6807                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6808                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6809
6810                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6811                                                 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6812                                 }
6813                         }
6814
6815                         // When one accessor does not exist and property hides base one
6816                         // we need to propagate this upwards
6817                         if (set_accessor == null)
6818                                 set_accessor = get_accessor;
6819
6820                         //
6821                         // Get the less restrictive access
6822                         //
6823                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6824                 }
6825
6826                 public override void Emit ()
6827                 {
6828                         //
6829                         // The PropertyBuilder can be null for explicit implementations, in that
6830                         // case, we do not actually emit the ".property", so there is nowhere to
6831                         // put the attribute
6832                         //
6833                         if (PropertyBuilder != null && OptAttributes != null)
6834                                 OptAttributes.Emit ();
6835
6836                         if (!Get.IsDummy)
6837                                 Get.Emit (Parent);
6838
6839                         if (!Set.IsDummy)
6840                                 Set.Emit (Parent);
6841
6842                         base.Emit ();
6843                 }
6844
6845                 /// <summary>
6846                 /// Tests whether accessors are not in collision with some method (CS0111)
6847                 /// </summary>
6848                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6849                 {
6850                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6851                 }
6852
6853                 public override bool IsUsed
6854                 {
6855                         get {
6856                                 if (IsExplicitImpl)
6857                                         return true;
6858
6859                                 return Get.IsUsed | Set.IsUsed;
6860                         }
6861                 }
6862
6863                 protected override void SetMemberName (MemberName new_name)
6864                 {
6865                         base.SetMemberName (new_name);
6866
6867                         Get.UpdateName (this);
6868                         Set.UpdateName (this);
6869                 }
6870
6871                 public override string[] ValidAttributeTargets {
6872                         get {
6873                                 return attribute_targets;
6874                         }
6875                 }
6876
6877                 //
6878                 //   Represents header string for documentation comment.
6879                 //
6880                 public override string DocCommentHeader {
6881                         get { return "P:"; }
6882                 }
6883         }
6884                         
6885         public class Property : PropertyBase {
6886                 const int AllowedModifiers =
6887                         Modifiers.NEW |
6888                         Modifiers.PUBLIC |
6889                         Modifiers.PROTECTED |
6890                         Modifiers.INTERNAL |
6891                         Modifiers.PRIVATE |
6892                         Modifiers.STATIC |
6893                         Modifiers.SEALED |
6894                         Modifiers.OVERRIDE |
6895                         Modifiers.ABSTRACT |
6896                         Modifiers.UNSAFE |
6897                         Modifiers.EXTERN |
6898                         Modifiers.METHOD_YIELDS |
6899                         Modifiers.VIRTUAL;
6900
6901                 const int AllowedInterfaceModifiers =
6902                         Modifiers.NEW;
6903
6904                 void CreateAutomaticProperty (Block block, Accessor get_block, Accessor set_block)
6905                 {
6906                         // Make the field
6907                         Field field = new Field (
6908                                 Parent, Type,
6909                                 Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & Modifiers.STATIC),
6910                                 CompilerGeneratedClass.MakeName (null, "CompilerGeneratedField"),
6911                                 null, Location);
6912                         ((TypeContainer)Parent).AddField (field);
6913
6914                         // Make get block
6915                         get_block.Block = new ToplevelBlock (block, null, Location);
6916                         Return r = new Return (new SimpleName(field.Name, Location), Location);
6917                         get_block.Block.AddStatement (r);
6918                         get_block.ModFlags |= Modifiers.COMPILER_GENERATED;
6919
6920                         // Make set block
6921                         Parameters parameters = new Parameters (new Parameter (Type, "value", Parameter.Modifier.NONE, null, Location));
6922                         set_block.Block = new ToplevelBlock (block, parameters, Location);
6923                         Assign a = new Assign (new SimpleName(field.Name, Location), new SimpleName ("value", Location));
6924                         set_block.Block.AddStatement (new StatementExpression(a));
6925                         set_block.ModFlags |= Modifiers.COMPILER_GENERATED;
6926                 }
6927
6928                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6929                                  MemberName name, Attributes attrs, Accessor get_block,
6930                                  Accessor set_block, bool define_set_first)
6931                         : this (parent, type, mod, is_iface, name, attrs, get_block, set_block,
6932                                 define_set_first, null)
6933                 {
6934                 }
6935                 
6936                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6937                                  MemberName name, Attributes attrs, Accessor get_block,
6938                                  Accessor set_block, bool define_set_first, Block current_block)
6939                         : base (parent, type, mod,
6940                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6941                                 is_iface, name, attrs, define_set_first)
6942                 {
6943                         if (RootContext.Version >= LanguageVersion.LINQ &&
6944                                 !is_iface &&
6945                                 (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
6946                                 get_block != null && get_block.Block == null &&
6947                                 set_block != null && set_block.Block == null)
6948                                 CreateAutomaticProperty (current_block, get_block, set_block);
6949
6950                         if (get_block == null)
6951                                 Get = new GetMethod (this);
6952                         else
6953                                 Get = new GetMethod (this, get_block);
6954
6955                         if (set_block == null)
6956                                 Set = new SetMethod (this);
6957                         else
6958                                 Set = new SetMethod (this, set_block);
6959                 }
6960
6961                 public override bool Define ()
6962                 {
6963                         if (!DoDefineBase ())
6964                                 return false;
6965
6966                         if (!base.Define ())
6967                                 return false;
6968
6969                         if (!CheckBase ())
6970                                 return false;
6971
6972                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6973
6974                         if (!DefineAccessors ())
6975                                 return false;
6976
6977                         // FIXME - PropertyAttributes.HasDefault ?
6978
6979                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6980                                 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6981
6982                         if (!Get.IsDummy)
6983                                 PropertyBuilder.SetGetMethod (GetBuilder);
6984                                 
6985                         if (!Set.IsDummy)
6986                                 PropertyBuilder.SetSetMethod (SetBuilder);
6987                         
6988                         TypeManager.RegisterProperty (PropertyBuilder, this);
6989                         return true;
6990                 }
6991
6992                 protected override PropertyInfo ResolveBaseProperty ()
6993                 {
6994                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
6995                                 Parent.TypeBuilder, Name, Parameters.EmptyReadOnlyParameters.Types, null, true) as PropertyInfo;
6996                 }
6997         }
6998
6999         /// </summary>
7000         ///  Gigantic workaround  for lameness in SRE follows :
7001         ///  This class derives from EventInfo and attempts to basically
7002         ///  wrap around the EventBuilder so that FindMembers can quickly
7003         ///  return this in it search for members
7004         /// </summary>
7005         public class MyEventBuilder : EventInfo {
7006                 
7007                 //
7008                 // We use this to "point" to our Builder which is
7009                 // not really a MemberInfo
7010                 //
7011                 EventBuilder MyBuilder;
7012                 
7013                 //
7014                 // We "catch" and wrap these methods
7015                 //
7016                 MethodInfo raise, remove, add;
7017
7018                 EventAttributes attributes;
7019                 Type declaring_type, reflected_type, event_type;
7020                 string name;
7021
7022                 Event my_event;
7023
7024                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
7025                 {
7026                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
7027
7028                         // And now store the values in our own fields.
7029                         
7030                         declaring_type = type_builder;
7031
7032                         reflected_type = type_builder;
7033                         
7034                         attributes = event_attr;
7035                         this.name = name;
7036                         my_event = ev;
7037                         this.event_type = event_type;
7038                 }
7039                 
7040                 //
7041                 // Methods that you have to override.  Note that you only need 
7042                 // to "implement" the variants that take the argument (those are
7043                 // the "abstract" methods, the others (GetAddMethod()) are 
7044                 // regular.
7045                 //
7046                 public override MethodInfo GetAddMethod (bool nonPublic)
7047                 {
7048                         return add;
7049                 }
7050                 
7051                 public override MethodInfo GetRemoveMethod (bool nonPublic)
7052                 {
7053                         return remove;
7054                 }
7055                 
7056                 public override MethodInfo GetRaiseMethod (bool nonPublic)
7057                 {
7058                         return raise;
7059                 }
7060                 
7061                 //
7062                 // These methods make "MyEventInfo" look like a Builder
7063                 //
7064                 public void SetRaiseMethod (MethodBuilder raiseMethod)
7065                 {
7066                         raise = raiseMethod;
7067                         MyBuilder.SetRaiseMethod (raiseMethod);
7068                 }
7069
7070                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
7071                 {
7072                         remove = removeMethod;
7073                         MyBuilder.SetRemoveOnMethod (removeMethod);
7074                 }
7075
7076                 public void SetAddOnMethod (MethodBuilder addMethod)
7077                 {
7078                         add = addMethod;
7079                         MyBuilder.SetAddOnMethod (addMethod);
7080                 }
7081
7082                 public void SetCustomAttribute (CustomAttributeBuilder cb)
7083                 {
7084                         MyBuilder.SetCustomAttribute (cb);
7085                 }
7086                 
7087                 public override object [] GetCustomAttributes (bool inherit)
7088                 {
7089                         // FIXME : There's nothing which can be seemingly done here because
7090                         // we have no way of getting at the custom attribute objects of the
7091                         // EventBuilder !
7092                         return null;
7093                 }
7094
7095                 public override object [] GetCustomAttributes (Type t, bool inherit)
7096                 {
7097                         // FIXME : Same here !
7098                         return null;
7099                 }
7100
7101                 public override bool IsDefined (Type t, bool b)
7102                 {
7103                         return true;
7104                 }
7105
7106                 public override EventAttributes Attributes {
7107                         get {
7108                                 return attributes;
7109                         }
7110                 }
7111
7112                 public override string Name {
7113                         get {
7114                                 return name;
7115                         }
7116                 }
7117
7118                 public override Type DeclaringType {
7119                         get {
7120                                 return declaring_type;
7121                         }
7122                 }
7123
7124                 public override Type ReflectedType {
7125                         get {
7126                                 return reflected_type;
7127                         }
7128                 }
7129
7130                 public Type EventType {
7131                         get {
7132                                 return event_type;
7133                         }
7134                 }
7135                 
7136                 public void SetUsed ()
7137                 {
7138                         if (my_event != null) {
7139 //                              my_event.SetAssigned ();
7140                                 my_event.SetMemberIsUsed ();
7141                         }
7142                 }
7143         }
7144         
7145         /// <summary>
7146         /// For case when event is declared like property (with add and remove accessors).
7147         /// </summary>
7148         public class EventProperty: Event {
7149                 abstract class AEventPropertyAccessor : AEventAccessor
7150                 {
7151                         readonly ArrayList anonymous_methods;
7152
7153                         public AEventPropertyAccessor (Event method, Accessor accessor, string prefix):
7154                                 base (method, accessor, prefix)
7155                         {
7156                                 this.anonymous_methods = accessor.AnonymousMethods;
7157                         }
7158
7159                         public override MethodBuilder Define (DeclSpace ds)
7160                         {
7161                                 CheckAbstractAndExtern (block != null);
7162                                 return base.Define (ds);
7163                         }
7164                         
7165                         public override string GetSignatureForError ()
7166                         {
7167                                 return method.GetSignatureForError () + "." + prefix.Substring (0, prefix.Length - 1);
7168                         }
7169
7170                         public override bool ResolveMembers ()
7171                         {
7172                                 if (anonymous_methods == null)
7173                                         return true;
7174
7175                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
7176                                         if (!ame.CreateAnonymousHelpers ())
7177                                                 return false;
7178                                 }
7179
7180                                 return true;
7181                         }
7182
7183                 }
7184
7185                 sealed class AddDelegateMethod: AEventPropertyAccessor
7186                 {
7187                         public AddDelegateMethod (Event method, Accessor accessor):
7188                                 base (method, accessor, "add_")
7189                         {
7190                         }
7191
7192                         protected override MethodInfo DelegateMethodInfo {
7193                                 get {
7194                                         return TypeManager.delegate_combine_delegate_delegate;
7195                                 }
7196                         }
7197                 }
7198
7199                 sealed class RemoveDelegateMethod: AEventPropertyAccessor
7200                 {
7201                         public RemoveDelegateMethod (Event method, Accessor accessor):
7202                                 base (method, accessor, "remove_")
7203                         {
7204                         }
7205
7206                         protected override MethodInfo DelegateMethodInfo {
7207                                 get {
7208                                         return TypeManager.delegate_remove_delegate_delegate;
7209                                 }
7210                         }
7211                 }
7212
7213
7214                 static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
7215
7216                 public EventProperty (DeclSpace parent, Expression type, int mod_flags,
7217                                       bool is_iface, MemberName name,
7218                                       Attributes attrs, Accessor add, Accessor remove)
7219                         : base (parent, type, mod_flags, is_iface, name, attrs)
7220                 {
7221                         Add = new AddDelegateMethod (this, add);
7222                         Remove = new RemoveDelegateMethod (this, remove);
7223                 }
7224
7225                 public override bool Define()
7226                 {
7227                         if (!base.Define ())
7228                                 return false;
7229
7230                         if (IsExplicitImpl)
7231                                 SetMemberIsUsed ();
7232
7233                         return true;
7234                 }
7235
7236                 public override string[] ValidAttributeTargets {
7237                         get {
7238                                 return attribute_targets;
7239                         }
7240                 }
7241         }
7242
7243         /// <summary>
7244         /// Event is declared like field.
7245         /// </summary>
7246         public class EventField : Event {
7247                 abstract class EventFieldAccessor : AEventAccessor
7248                 {
7249                         protected EventFieldAccessor (Event method, string prefix)
7250                                 : base (method, prefix)
7251                         {
7252                         }
7253
7254                         protected override void EmitMethod(DeclSpace parent)
7255                         {
7256                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7257                                         return;
7258
7259                                 MethodBuilder mb = method_data.MethodBuilder;
7260                                 ILGenerator ig = mb.GetILGenerator ();
7261
7262                                 // TODO: because we cannot use generics yet
7263                                 FieldInfo field_info = ((EventField)method).FieldBuilder;
7264
7265                                 mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
7266                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
7267                                         ig.Emit (OpCodes.Ldsfld, field_info);
7268                                         ig.Emit (OpCodes.Ldarg_0);
7269                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7270                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7271                                         ig.Emit (OpCodes.Stsfld, field_info);
7272                                 } else {
7273                                         ig.Emit (OpCodes.Ldarg_0);
7274                                         ig.Emit (OpCodes.Ldarg_0);
7275                                         ig.Emit (OpCodes.Ldfld, field_info);
7276                                         ig.Emit (OpCodes.Ldarg_1);
7277                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7278                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7279                                         ig.Emit (OpCodes.Stfld, field_info);
7280                                 }
7281                                 ig.Emit (OpCodes.Ret);
7282                         }
7283                 }
7284
7285                 sealed class AddDelegateMethod: EventFieldAccessor
7286                 {
7287                         public AddDelegateMethod (Event method):
7288                                 base (method, "add_")
7289                         {
7290                         }
7291
7292                         protected override MethodInfo DelegateMethodInfo {
7293                                 get {
7294                                         return TypeManager.delegate_combine_delegate_delegate;
7295                                 }
7296                         }
7297                 }
7298
7299                 sealed class RemoveDelegateMethod: EventFieldAccessor
7300                 {
7301                         public RemoveDelegateMethod (Event method):
7302                                 base (method, "remove_")
7303                         {
7304                         }
7305
7306                         protected override MethodInfo DelegateMethodInfo {
7307                                 get {
7308                                         return TypeManager.delegate_remove_delegate_delegate;
7309                                 }
7310                         }
7311                 }
7312
7313
7314                 static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
7315                 static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
7316
7317                 public FieldBuilder FieldBuilder;
7318                 public Expression Initializer;
7319
7320                 public EventField (DeclSpace parent, Expression type, int mod_flags,
7321                                    bool is_iface, MemberName name,
7322                                    Attributes attrs)
7323                         : base (parent, type, mod_flags, is_iface, name, attrs)
7324                 {
7325                         Add = new AddDelegateMethod (this);
7326                         Remove = new RemoveDelegateMethod (this);
7327                 }
7328
7329                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7330                 {
7331                         if (a.Target == AttributeTargets.Field) {
7332                                 FieldBuilder.SetCustomAttribute (cb);
7333                                 return;
7334                         }
7335
7336                         if (a.Target == AttributeTargets.Method) {
7337                                 int errors = Report.Errors;
7338                                 Add.ApplyAttributeBuilder (a, cb);
7339                                 if (errors == Report.Errors)
7340                                         Remove.ApplyAttributeBuilder (a, cb);
7341                                 return;
7342                         }
7343
7344                         base.ApplyAttributeBuilder (a, cb);
7345                 }
7346
7347                 public override bool Define()
7348                 {
7349                         if (!base.Define ())
7350                                 return false;
7351
7352                         if (IsInterface)
7353                                 return true;
7354
7355                         // FIXME: We are unable to detect whether generic event is used because
7356                         // we are using FieldExpr instead of EventExpr for event access in that
7357                         // case.  When this issue will be fixed this hack can be removed.
7358                         if (TypeManager.IsGenericType (MemberType))
7359                                 SetMemberIsUsed();
7360
7361                         FieldBuilder = Parent.TypeBuilder.DefineField (
7362                                 Name, MemberType,
7363                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7364                         TypeManager.RegisterEventField (EventBuilder, this);
7365
7366                         if (Initializer != null) {
7367                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
7368                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
7369                                                 GetSignatureForError ());
7370                                         return false;
7371                                 }
7372
7373                                 Parent.PartialContainer.RegisterFieldForInitialization (this,
7374                                         new FieldInitializer (FieldBuilder, Initializer, Parent));
7375                         }
7376
7377                         return true;
7378                 }
7379
7380                 public override string[] ValidAttributeTargets 
7381                 {
7382                         get {
7383                                 return IsInterface ? attribute_targets_interface : attribute_targets;
7384                         }
7385                 }
7386         }
7387
7388         public abstract class Event : PropertyBasedMember {
7389                 public abstract class AEventAccessor : AbstractPropertyEventMethod
7390                 {
7391                         protected readonly Event method;
7392                         ImplicitParameter param_attr;
7393
7394                         static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
7395
7396                         protected AEventAccessor (Event method, string prefix)
7397                                 : base (method, prefix)
7398                         {
7399                                 this.method = method;
7400                                 this.ModFlags = method.ModFlags;
7401                         }
7402
7403                         protected AEventAccessor (Event method, Accessor accessor, string prefix)
7404                                 : base (method, accessor, prefix)
7405                         {
7406                                 this.method = method;
7407                                 this.ModFlags = method.ModFlags;
7408                         }
7409
7410                         public override Iterator Iterator {
7411                                 get { return null; }
7412                         }
7413
7414                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7415                         {
7416                                 if (a.IsInternalMethodImplAttribute) {
7417                                         method.is_external_implementation = true;
7418                                 }
7419
7420                                 base.ApplyAttributeBuilder (a, cb);
7421                         }
7422
7423                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
7424                         {
7425                                 if (a.Target == AttributeTargets.Parameter) {
7426                                         if (param_attr == null)
7427                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
7428
7429                                         param_attr.ApplyAttributeBuilder (a, cb);
7430                                         return;
7431                                 }
7432
7433                                 base.ApplyAttributeBuilder (a, cb);
7434                         }
7435
7436                         public override AttributeTargets AttributeTargets {
7437                                 get {
7438                                         return AttributeTargets.Method;
7439                                 }
7440                         }
7441
7442                         public override bool IsClsComplianceRequired ()
7443                         {
7444                                 return method.IsClsComplianceRequired ();
7445                         }
7446
7447                         public virtual MethodBuilder Define (DeclSpace parent)
7448                         {
7449                                 method_data = new MethodData (method, method.ModFlags,
7450                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
7451
7452                                 if (!method_data.Define (parent))
7453                                         return null;
7454
7455                                 MethodBuilder mb = method_data.MethodBuilder;
7456                                 ParameterInfo.ApplyAttributes (mb);
7457                                 return mb;
7458                         }
7459
7460                         protected abstract MethodInfo DelegateMethodInfo { get; }
7461
7462                         public override Type ReturnType {
7463                                 get {
7464                                         return TypeManager.void_type;
7465                                 }
7466                         }
7467
7468                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
7469                         {
7470                                 return new EmitContext (
7471                                         ds, method.Parent, Location, ig, ReturnType,
7472                                         method.ModFlags, false);
7473                         }
7474
7475                         public override ObsoleteAttribute GetObsoleteAttribute ()
7476                         {
7477                                 return method.GetObsoleteAttribute ();
7478                         }
7479
7480                         public override string[] ValidAttributeTargets {
7481                                 get {
7482                                         return attribute_targets;
7483                                 }
7484                         }
7485
7486                         public override Parameters ParameterInfo {
7487                                 get {
7488                                         return method.parameters;
7489                                 }
7490                         }
7491                 }
7492
7493
7494                 const int AllowedModifiers =
7495                         Modifiers.NEW |
7496                         Modifiers.PUBLIC |
7497                         Modifiers.PROTECTED |
7498                         Modifiers.INTERNAL |
7499                         Modifiers.PRIVATE |
7500                         Modifiers.STATIC |
7501                         Modifiers.VIRTUAL |
7502                         Modifiers.SEALED |
7503                         Modifiers.OVERRIDE |
7504                         Modifiers.UNSAFE |
7505                         Modifiers.ABSTRACT |
7506                         Modifiers.EXTERN;
7507
7508                 const int AllowedInterfaceModifiers =
7509                         Modifiers.NEW;
7510
7511                 public AEventAccessor Add, Remove;
7512                 public MyEventBuilder     EventBuilder;
7513                 public MethodBuilder AddBuilder, RemoveBuilder;
7514
7515                 Parameters parameters;
7516
7517                 protected Event (DeclSpace parent, Expression type, int mod_flags,
7518                               bool is_iface, MemberName name, Attributes attrs)
7519                         : base (parent, null, type, mod_flags,
7520                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers, is_iface,
7521                                 name, attrs)
7522                 {
7523                 }
7524
7525                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7526                 {
7527                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7528                                 a.Error_InvalidSecurityParent ();
7529                                 return;
7530                         }
7531                         
7532                         EventBuilder.SetCustomAttribute (cb);
7533                 }
7534
7535                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7536                 {
7537                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7538                 }
7539
7540                 public override AttributeTargets AttributeTargets {
7541                         get {
7542                                 return AttributeTargets.Event;
7543                         }
7544                 }
7545
7546                 public override bool Define ()
7547                 {
7548                         if (!DoDefineBase ())
7549                                 return false;
7550
7551                         if (!DoDefine ())
7552                                 return false;
7553
7554                         if (!TypeManager.IsDelegateType (MemberType)) {
7555                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7556                                 return false;
7557                         }
7558
7559                         parameters = Parameters.CreateFullyResolved (
7560                                 new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location));
7561
7562                         if (!CheckBase ())
7563                                 return false;
7564
7565                         //
7566                         // Now define the accessors
7567                         //
7568
7569                         AddBuilder = Add.Define (Parent);
7570                         if (AddBuilder == null)
7571                                 return false;
7572
7573                         RemoveBuilder = Remove.Define (Parent);
7574                         if (RemoveBuilder == null)
7575                                 return false;
7576
7577                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
7578                         EventBuilder.SetAddOnMethod (AddBuilder);
7579                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7580                         return true;
7581                 }
7582
7583                 public override void Emit ()
7584                 {
7585                         if (OptAttributes != null) {
7586                                 OptAttributes.Emit ();
7587                         }
7588
7589                         Add.Emit (Parent);
7590                         Remove.Emit (Parent);
7591
7592                         base.Emit ();
7593                 }
7594
7595                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7596                 {
7597                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
7598                                 Parent.TypeBuilder, Name);
7599
7600                         if (mi == null)
7601                                 return null;
7602
7603                         ParameterData pd = TypeManager.GetParameterData (mi);
7604                         base_ret_type = pd.ParameterType (0);
7605                         return mi;
7606                 }
7607
7608                 //
7609                 //   Represents header string for documentation comment.
7610                 //
7611                 public override string DocCommentHeader {
7612                         get { return "E:"; }
7613                 }
7614         }
7615
7616  
7617         public class Indexer : PropertyBase {
7618
7619                 class GetIndexerMethod : GetMethod
7620                 {
7621                         public GetIndexerMethod (PropertyBase method):
7622                                 base (method)
7623                         {
7624                         }
7625
7626                         public GetIndexerMethod (PropertyBase method, Accessor accessor):
7627                                 base (method, accessor)
7628                         {
7629                         }
7630
7631                         public override Parameters ParameterInfo {
7632                                 get {
7633                                         return ((Indexer)method).parameters;
7634                                 }
7635                         }
7636                 }
7637
7638                 class SetIndexerMethod: SetMethod
7639                 {
7640                         public SetIndexerMethod (PropertyBase method):
7641                                 base (method)
7642                         {
7643                         }
7644
7645                         public SetIndexerMethod (PropertyBase method, Accessor accessor):
7646                                 base (method, accessor)
7647                         {
7648                         }
7649
7650                         protected override void DefineParameters ()
7651                         {
7652                                 parameters = Parameters.MergeGenerated (((Indexer)method).parameters,
7653                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7654                         }
7655                 }
7656
7657                 const int AllowedModifiers =
7658                         Modifiers.NEW |
7659                         Modifiers.PUBLIC |
7660                         Modifiers.PROTECTED |
7661                         Modifiers.INTERNAL |
7662                         Modifiers.PRIVATE |
7663                         Modifiers.VIRTUAL |
7664                         Modifiers.SEALED |
7665                         Modifiers.OVERRIDE |
7666                         Modifiers.UNSAFE |
7667                         Modifiers.EXTERN |
7668                         Modifiers.ABSTRACT;
7669
7670                 const int AllowedInterfaceModifiers =
7671                         Modifiers.NEW;
7672
7673                 public readonly Parameters parameters;
7674
7675                 public Indexer (DeclSpace parent, Expression type, MemberName name, int mod,
7676                                 bool is_iface, Parameters parameters, Attributes attrs,
7677                                 Accessor get_block, Accessor set_block, bool define_set_first)
7678                         : base (parent, type, mod,
7679                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7680                                 is_iface, name, attrs, define_set_first)
7681                 {
7682                         if (type == TypeManager.system_void_expr)
7683                                 Report.Error (620, name.Location, "An indexer return type cannot be `void'");
7684                         
7685                         this.parameters = parameters;
7686
7687                         if (get_block == null)
7688                                 Get = new GetIndexerMethod (this);
7689                         else
7690                                 Get = new GetIndexerMethod (this, get_block);
7691
7692                         if (set_block == null)
7693                                 Set = new SetIndexerMethod (this);
7694                         else
7695                                 Set = new SetIndexerMethod (this, set_block);
7696                 }
7697                 
7698                 protected override bool CheckForDuplications ()
7699                 {
7700                         ArrayList ar = Parent.PartialContainer.Indexers;
7701                         if (ar != null) {
7702                                 int arLen = ar.Count;
7703                                         
7704                                 for (int i = 0; i < arLen; i++) {
7705                                         Indexer m = (Indexer) ar [i];
7706                                         if (IsDuplicateImplementation (m))
7707                                                 return false;
7708                                 }
7709                         }
7710
7711                         return true;
7712                 }
7713
7714                 bool IsDuplicateImplementation (Indexer indexer)
7715                 {
7716                         if (this == indexer)
7717                                 return false;
7718
7719                         if (!MemberName.Equals (indexer.MemberName))
7720                                 return false;
7721
7722                         Type[] param_types = indexer.parameters.Types;
7723
7724                         // When it is not yet defined
7725                         if (param_types == null)
7726                                 return false;
7727
7728                         if (param_types.Length != parameters.Count)
7729                                 return false;
7730
7731                         for (int i = 0; i < param_types.Length; i++)
7732                                 if (param_types [i] != parameters.Types [i])
7733                                         return false;
7734
7735                         Report.SymbolRelatedToPreviousError (indexer);
7736                         Report.Error (111, Location, TypeContainer.Error111, indexer.GetSignatureForError ());
7737                         return true;
7738                 }
7739
7740
7741                 public override bool Define ()
7742                 {
7743                         if (!DoDefineBase ())
7744                                 return false;
7745
7746                         if (!base.Define ())
7747                                 return false;
7748
7749                         if (!DefineParameters (parameters))
7750                                 return false;
7751
7752                         if (OptAttributes != null) {
7753                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7754                                 if (indexer_attr != null) {
7755                                         // Remove the attribute from the list because it is not emitted
7756                                         OptAttributes.Attrs.Remove (indexer_attr);
7757
7758                                         string name = indexer_attr.GetIndexerAttributeValue ();
7759                                         if (name == null)
7760                                                 return false;
7761
7762                                         ShortName = name;
7763
7764                                         if (IsExplicitImpl) {
7765                                                 Report.Error (415, indexer_attr.Location,
7766                                                               "The `IndexerName' attribute is valid only on an " +
7767                                                               "indexer that is not an explicit interface member declaration");
7768                                                 return false;
7769                                         }
7770
7771                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7772                                                 Report.Error (609, indexer_attr.Location,
7773                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7774                                                 return false;
7775                                         }
7776                                 }
7777                         }
7778
7779                         if (InterfaceType != null) {
7780                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7781                                 if (base_IndexerName != Name)
7782                                         ShortName = base_IndexerName;
7783                         }
7784
7785                         if (!Parent.PartialContainer.AddMember (this) ||
7786                                 !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
7787                                 return false;
7788
7789                         if (!CheckBase ())
7790                                 return false;
7791
7792                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7793                         
7794                         if (!DefineAccessors ())
7795                                 return false;
7796
7797                         if (!Get.IsDummy) {
7798                                 // Setup iterator if we are one
7799                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7800                                         Iterator iterator = Iterator.CreateIterator (Get, Parent, null, ModFlags);
7801                                         if (iterator == null)
7802                                                 return false;
7803                                 }
7804                         }
7805
7806                         //
7807                         // Now name the parameters
7808                         //
7809                         Parameter [] p = parameters.FixedParameters;
7810                         if (p != null) {
7811                                 // TODO: should be done in parser and it needs to do cycle
7812                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7813                                         CSharpParser.Error_ParameterModifierNotValid (Location);
7814                                         return false;
7815                                 }
7816                         }
7817
7818                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7819                                 Name, PropertyAttributes.None, MemberType, parameters.Types);
7820                         
7821                         if (!Get.IsDummy)
7822                                 PropertyBuilder.SetGetMethod (GetBuilder);
7823
7824                         if (!Set.IsDummy)
7825                                 PropertyBuilder.SetSetMethod (SetBuilder);
7826                                 
7827                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, parameters.Types);
7828
7829                         return true;
7830                 }
7831
7832                 public override string GetDocCommentName (DeclSpace ds)
7833                 {
7834                         return DocUtil.GetMethodDocCommentName (this, parameters, ds);
7835                 }
7836
7837                 public override string GetSignatureForError ()
7838                 {
7839                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7840                         if (MemberName.Left != null) {
7841                                 sb.Append ('.');
7842                                 sb.Append (MemberName.Left);
7843                         }
7844
7845                         sb.Append (".this");
7846                         sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7847                         return sb.ToString ();
7848                 }
7849
7850                 public override bool MarkForDuplicationCheck ()
7851                 {
7852                         caching_flags |= Flags.TestMethodDuplication;
7853                         return true;
7854                 }
7855
7856                 protected override PropertyInfo ResolveBaseProperty ()
7857                 {
7858                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
7859                                 Parent.TypeBuilder, Name, parameters.Types, null, true) as PropertyInfo;
7860                 }
7861
7862                 protected override bool VerifyClsCompliance ()
7863                 {
7864                         if (!base.VerifyClsCompliance ())
7865                                 return false;
7866
7867                         parameters.VerifyClsCompliance ();
7868                         return true;
7869                 }
7870         }
7871
7872         public class Operator : MethodOrOperator, IAnonymousHost {
7873
7874                 const int AllowedModifiers =
7875                         Modifiers.PUBLIC |
7876                         Modifiers.UNSAFE |
7877                         Modifiers.EXTERN |
7878                         Modifiers.STATIC;
7879
7880                 public enum OpType : byte {
7881
7882                         // Unary operators
7883                         LogicalNot,
7884                         OnesComplement,
7885                         Increment,
7886                         Decrement,
7887                         True,
7888                         False,
7889
7890                         // Unary and Binary operators
7891                         Addition,
7892                         Subtraction,
7893
7894                         UnaryPlus,
7895                         UnaryNegation,
7896                         
7897                         // Binary operators
7898                         Multiply,
7899                         Division,
7900                         Modulus,
7901                         BitwiseAnd,
7902                         BitwiseOr,
7903                         ExclusiveOr,
7904                         LeftShift,
7905                         RightShift,
7906                         Equality,
7907                         Inequality,
7908                         GreaterThan,
7909                         LessThan,
7910                         GreaterThanOrEqual,
7911                         LessThanOrEqual,
7912
7913                         // Implicit and Explicit
7914                         Implicit,
7915                         Explicit,
7916
7917                         // Just because of enum
7918                         TOP
7919                 };
7920
7921                 public readonly OpType OperatorType;
7922                 
7923                 public Operator (DeclSpace parent, OpType type, Expression ret_type,
7924                                  int mod_flags, Parameters parameters,
7925                                  ToplevelBlock block, Attributes attrs, Location loc)
7926                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7927                                 new MemberName ("op_" + type.ToString(), loc), attrs, parameters)
7928                 {
7929                         OperatorType = type;
7930                         Block = block;
7931                 }
7932
7933                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7934                 {
7935                         if (a.Type == TypeManager.conditional_attribute_type) {
7936                                 Error_ConditionalAttributeIsNotValid ();
7937                                 return;
7938                         }
7939
7940                         base.ApplyAttributeBuilder (a, cb);
7941                 }
7942                 
7943                 protected override bool CheckForDuplications ()
7944                 {
7945                         ArrayList ar = Parent.PartialContainer.Operators;
7946                         if (ar != null) {
7947                                 int arLen = ar.Count;
7948                                         
7949                                 for (int i = 0; i < arLen; i++) {
7950                                         Operator o = (Operator) ar [i];
7951                                         if (IsDuplicateImplementation (o))
7952                                                 return false;
7953                                 }
7954                         }
7955
7956                         ar = Parent.PartialContainer.Methods;
7957                         if (ar != null) {
7958                                 int arLen = ar.Count;
7959                                         
7960                                 for (int i = 0; i < arLen; i++) {
7961                                         Method m = (Method) ar [i];
7962                                         if (IsDuplicateImplementation (m))
7963                                                 return false;
7964                                 }
7965                         }
7966
7967                         return true;
7968                 }
7969
7970                 public override bool Define ()
7971                 {
7972                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7973                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7974                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7975                                 return false;
7976                         }
7977
7978                         // imlicit and explicit operator of same types are not allowed
7979                         if (OperatorType == OpType.Explicit || OperatorType == OpType.Implicit)
7980                                 MarkForDuplicationCheck ();
7981
7982                         if (!base.Define ())
7983                                 return false;
7984
7985                         if (MemberType == TypeManager.void_type) {
7986                                 Report.Error (590, Location, "User-defined operators cannot return void");
7987                                 return false;
7988                         }
7989
7990                         Type declaring_type = MethodData.DeclaringType;
7991                         Type return_type = MemberType;
7992                         Type first_arg_type = ParameterTypes [0];
7993
7994                         // Rules for conversion operators
7995                         
7996                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7997                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7998                                         Report.Error (555, Location,
7999                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
8000                                         return false;
8001                                 }
8002                                 
8003                                 if ((first_arg_type != declaring_type) && (return_type != declaring_type) &&
8004                                     !TypeManager.IsNullableTypeOf (first_arg_type, declaring_type) &&
8005                                     !TypeManager.IsNullableTypeOf (return_type, declaring_type)) {
8006                                         Report.Error (
8007                                                 556, Location, 
8008                                                 "User-defined conversion must convert to or from the " +
8009                                                 "enclosing type");
8010                                         return false;
8011                                 }
8012
8013                                 if (first_arg_type.IsInterface || return_type.IsInterface){
8014                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
8015                                                 GetSignatureForError ());
8016                                         return false;
8017                                 }
8018                                 
8019                                 if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)) {
8020                                         if (declaring_type.IsSubclassOf (return_type) || declaring_type.IsSubclassOf (first_arg_type)) {
8021                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
8022                                                         GetSignatureForError ());
8023                                                 return false;
8024                                         }
8025                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
8026                                                 GetSignatureForError ());
8027                                         return false;
8028                                 }
8029                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
8030                                 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
8031                                         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");
8032                                         return false;
8033                                 }
8034                         } else if (Parameters.Count == 1) {
8035                                 // Checks for Unary operators
8036
8037                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
8038                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
8039                                                 Report.Error (448, Location,
8040                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
8041                                                 return false;
8042                                         }
8043                                         if (first_arg_type != declaring_type) {
8044                                                 Report.Error (
8045                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
8046                                                 return false;
8047                                         }
8048                                 }
8049                                 
8050                                 if (first_arg_type != declaring_type){
8051                                         Report.Error (
8052                                                 562, Location,
8053                                                 "The parameter of a unary operator must be the " +
8054                                                 "containing type");
8055                                         return false;
8056                                 }
8057                                 
8058                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
8059                                         if (return_type != TypeManager.bool_type){
8060                                                 Report.Error (
8061                                                         215, Location,
8062                                                         "The return type of operator True or False " +
8063                                                         "must be bool");
8064                                                 return false;
8065                                         }
8066                                 }
8067                                 
8068                         } else {
8069                                 // Checks for Binary operators
8070                                 
8071                                 if (first_arg_type != declaring_type &&
8072                                     ParameterTypes [1] != declaring_type){
8073                                         Report.Error (
8074                                                 563, Location,
8075                                                 "One of the parameters of a binary operator must " +
8076                                                 "be the containing type");
8077                                         return false;
8078                                 }
8079                         }
8080
8081                         return true;
8082                 }
8083
8084                 protected override bool DoDefine ()
8085                 {
8086                         if (!base.DoDefine ())
8087                                 return false;
8088
8089                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
8090                         return true;
8091                 }
8092                 
8093                 public override void Emit ()
8094                 {
8095                         base.Emit ();
8096
8097                         Parameters.ApplyAttributes (MethodBuilder);
8098
8099                         //
8100                         // abstract or extern methods have no bodies
8101                         //
8102                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
8103                                 return;
8104                         
8105                         EmitContext ec;
8106                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
8107                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
8108                         else
8109                                 ec = CreateEmitContext (Parent, null);
8110                         
8111                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
8112                         ec.EmitTopBlock (this, Block);
8113
8114                         if (source != null)
8115                                 source.CloseMethod ();
8116
8117                         Block = null;
8118                 }
8119
8120                 // Operator cannot be override
8121                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
8122                 {
8123                         return null;
8124                 }
8125
8126                 public static string GetName (OpType ot)
8127                 {
8128                         switch (ot){
8129                         case OpType.LogicalNot:
8130                                 return "!";
8131                         case OpType.OnesComplement:
8132                                 return "~";
8133                         case OpType.Increment:
8134                                 return "++";
8135                         case OpType.Decrement:
8136                                 return "--";
8137                         case OpType.True:
8138                                 return "true";
8139                         case OpType.False:
8140                                 return "false";
8141                         case OpType.Addition:
8142                                 return "+";
8143                         case OpType.Subtraction:
8144                                 return "-";
8145                         case OpType.UnaryPlus:
8146                                 return "+";
8147                         case OpType.UnaryNegation:
8148                                 return "-";
8149                         case OpType.Multiply:
8150                                 return "*";
8151                         case OpType.Division:
8152                                 return "/";
8153                         case OpType.Modulus:
8154                                 return "%";
8155                         case OpType.BitwiseAnd:
8156                                 return "&";
8157                         case OpType.BitwiseOr:
8158                                 return "|";
8159                         case OpType.ExclusiveOr:
8160                                 return "^";
8161                         case OpType.LeftShift:
8162                                 return "<<";
8163                         case OpType.RightShift:
8164                                 return ">>";
8165                         case OpType.Equality:
8166                                 return "==";
8167                         case OpType.Inequality:
8168                                 return "!=";
8169                         case OpType.GreaterThan:
8170                                 return ">";
8171                         case OpType.LessThan:
8172                                 return "<";
8173                         case OpType.GreaterThanOrEqual:
8174                                 return ">=";
8175                         case OpType.LessThanOrEqual:
8176                                 return "<=";
8177                         case OpType.Implicit:
8178                                 return "implicit";
8179                         case OpType.Explicit:
8180                                 return "explicit";
8181                         default: return "";
8182                         }
8183                 }
8184
8185                 public static OpType GetOperatorType (string name)
8186                 {
8187                         if (name.StartsWith ("op_")){
8188                                 for (int i = 0; i < Unary.oper_names.Length; ++i) {
8189                                         if (Unary.oper_names [i] == name)
8190                                                 return (OpType)i;
8191                                 }
8192
8193                                 for (int i = 0; i < Binary.oper_names.Length; ++i) {
8194                                         if (Binary.oper_names [i] == name)
8195                                                 return (OpType)i;
8196                                 }
8197                         }
8198                         return OpType.TOP;
8199                 }
8200
8201                 public override string GetSignatureForError ()
8202                 {
8203                         StringBuilder sb = new StringBuilder ();
8204                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
8205                                 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
8206                         }
8207                         else {
8208                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
8209                         }
8210
8211                         sb.Append (Parameters.GetSignatureForError ());
8212                         return sb.ToString ();
8213                 }
8214         }
8215
8216         //
8217         // This is used to compare method signatures
8218         //
8219         struct MethodSignature {
8220                 public string Name;
8221                 public Type RetType;
8222                 public Type [] Parameters;
8223                 
8224                 /// <summary>
8225                 ///    This delegate is used to extract methods which have the
8226                 ///    same signature as the argument
8227                 /// </summary>
8228                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
8229                 
8230                 public MethodSignature (string name, Type ret_type, Type [] parameters)
8231                 {
8232                         Name = name;
8233                         RetType = ret_type;
8234
8235                         if (parameters == null)
8236                                 Parameters = Type.EmptyTypes;
8237                         else
8238                                 Parameters = parameters;
8239                 }
8240
8241                 public override string ToString ()
8242                 {
8243                         string pars = "";
8244                         if (Parameters.Length != 0){
8245                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
8246                                 for (int i = 0; i < Parameters.Length; i++){
8247                                         sb.Append (Parameters [i]);
8248                                         if (i+1 < Parameters.Length)
8249                                                 sb.Append (", ");
8250                                 }
8251                                 pars = sb.ToString ();
8252                         }
8253
8254                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
8255                 }
8256                 
8257                 public override int GetHashCode ()
8258                 {
8259                         return Name.GetHashCode ();
8260                 }
8261
8262                 public override bool Equals (Object o)
8263                 {
8264                         MethodSignature other = (MethodSignature) o;
8265
8266                         if (other.Name != Name)
8267                                 return false;
8268
8269                         if (other.RetType != RetType)
8270                                 return false;
8271                         
8272                         if (Parameters == null){
8273                                 if (other.Parameters == null)
8274                                         return true;
8275                                 return false;
8276                         }
8277
8278                         if (other.Parameters == null)
8279                                 return false;
8280                         
8281                         int c = Parameters.Length;
8282                         if (other.Parameters.Length != c)
8283                                 return false;
8284
8285                         for (int i = 0; i < c; i++)
8286                                 if (other.Parameters [i] != Parameters [i])
8287                                         return false;
8288
8289                         return true;
8290                 }
8291
8292                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
8293                 {
8294                         MethodSignature sig = (MethodSignature) filter_criteria;
8295
8296                         if (m.Name != sig.Name)
8297                                 return false;
8298
8299                         Type ReturnType;
8300                         MethodInfo mi = m as MethodInfo;
8301                         PropertyInfo pi = m as PropertyInfo;
8302
8303                         if (mi != null)
8304                                 ReturnType = mi.ReturnType;
8305                         else if (pi != null)
8306                                 ReturnType = pi.PropertyType;
8307                         else
8308                                 return false;
8309                         
8310                         //
8311                         // we use sig.RetType == null to mean `do not check the
8312                         // method return value.  
8313                         //
8314                         if (sig.RetType != null)
8315                                 if (ReturnType != sig.RetType)
8316                                         return false;
8317
8318                         Type [] args;
8319                         if (mi != null)
8320                                 args = TypeManager.GetParameterData (mi).Types;
8321                         else
8322                                 args = TypeManager.GetArgumentTypes (pi);
8323                         Type [] sigp = sig.Parameters;
8324
8325                         if (args.Length != sigp.Length)
8326                                 return false;
8327
8328                         for (int i = args.Length; i > 0; ){
8329                                 i--;
8330                                 if (args [i] != sigp [i])
8331                                         return false;
8332                         }
8333                         return true;
8334                 }
8335         }
8336 }
8337