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