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