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