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