Don't emit reaonly. prefix for reference loads
[mono.git] / mcs / mcs / decl.cs
1 //
2 // decl.cs: Declaration base class for structs, classes, enums and interfaces.
3 //
4 // Author: Miguel de Icaza (miguel@gnu.org)
5 //         Marek Safar (marek.safar@seznam.cz)
6 //
7 // Dual licensed under the terms of the MIT X11 or GNU GPL
8 //
9 // Copyright 2001 Ximian, Inc (http://www.ximian.com)
10 // Copyright 2004-2008 Novell, Inc
11 //
12 //
13
14 using System;
15 using System.Collections.Generic;
16 using System.Diagnostics;
17
18 #if NET_2_1
19 using XmlElement = System.Object;
20 #else
21 using System.Xml;
22 #endif
23
24 #if STATIC
25 using IKVM.Reflection;
26 using IKVM.Reflection.Emit;
27 #else
28 using System.Reflection;
29 using System.Reflection.Emit;
30 #endif
31
32 namespace Mono.CSharp {
33
34         //
35         // Better name would be DottenName
36         //
37         [DebuggerDisplay ("{GetSignatureForError()}")]
38         public class MemberName {
39                 public readonly string Name;
40                 public TypeArguments TypeArguments;
41
42                 public readonly MemberName Left;
43                 public readonly Location Location;
44
45                 public static readonly MemberName Null = new MemberName ("");
46
47                 bool is_double_colon;
48
49                 private MemberName (MemberName left, string name, bool is_double_colon,
50                                     Location loc)
51                 {
52                         this.Name = name;
53                         this.Location = loc;
54                         this.is_double_colon = is_double_colon;
55                         this.Left = left;
56                 }
57
58                 private MemberName (MemberName left, string name, bool is_double_colon,
59                                     TypeArguments args, Location loc)
60                         : this (left, name, is_double_colon, loc)
61                 {
62                         if (args != null && args.Count > 0)
63                                 this.TypeArguments = args;
64                 }
65
66                 public MemberName (string name)
67                         : this (name, Location.Null)
68                 { }
69
70                 public MemberName (string name, Location loc)
71                         : this (null, name, false, loc)
72                 { }
73
74                 public MemberName (string name, TypeArguments args, Location loc)
75                         : this (null, name, false, args, loc)
76                 { }
77
78                 public MemberName (MemberName left, string name)
79                         : this (left, name, left != null ? left.Location : Location.Null)
80                 { }
81
82                 public MemberName (MemberName left, string name, Location loc)
83                         : this (left, name, false, loc)
84                 { }
85
86                 public MemberName (MemberName left, string name, TypeArguments args, Location loc)
87                         : this (left, name, false, args, loc)
88                 { }
89
90                 public MemberName (string alias, string name, TypeArguments args, Location loc)
91                         : this (new MemberName (alias, loc), name, true, args, loc)
92                 { }
93
94                 public MemberName (MemberName left, MemberName right)
95                         : this (left, right, right.Location)
96                 { }
97
98                 public MemberName (MemberName left, MemberName right, Location loc)
99                         : this (null, right.Name, false, right.TypeArguments, loc)
100                 {
101                         if (right.is_double_colon)
102                                 throw new InternalErrorException ("Cannot append double_colon member name");
103                         this.Left = (right.Left == null) ? left : new MemberName (left, right.Left);
104                 }
105
106                 // TODO: Remove
107                 public string GetName ()
108                 {
109                         return GetName (false);
110                 }
111
112                 public int Arity {
113                         get {
114                                 return TypeArguments == null ? 0 : TypeArguments.Count;
115                         }
116                 }
117
118                 public bool IsGeneric {
119                         get {
120                                 if (TypeArguments != null)
121                                         return true;
122                                 else if (Left != null)
123                                         return Left.IsGeneric;
124                                 else
125                                         return false;
126                         }
127                 }
128
129                 public string GetName (bool is_generic)
130                 {
131                         string name = is_generic ? Basename : Name;
132                         if (Left != null)
133                                 return Left.GetName (is_generic) + (is_double_colon ? "::" : ".") + name;
134
135                         return name;
136                 }
137
138                 public ATypeNameExpression GetTypeExpression ()
139                 {
140                         if (Left == null) {
141                                 if (TypeArguments != null)
142                                         return new SimpleName (Name, TypeArguments, Location);
143                                 
144                                 return new SimpleName (Name, Location);
145                         }
146
147                         if (is_double_colon) {
148                                 if (Left.Left != null)
149                                         throw new InternalErrorException ("The left side of a :: should be an identifier");
150                                 return new QualifiedAliasMember (Left.Name, Name, TypeArguments, Location);
151                         }
152
153                         Expression lexpr = Left.GetTypeExpression ();
154                         return new MemberAccess (lexpr, Name, TypeArguments, Location);
155                 }
156
157                 public MemberName Clone ()
158                 {
159                         MemberName left_clone = Left == null ? null : Left.Clone ();
160                         return new MemberName (left_clone, Name, is_double_colon, TypeArguments, Location);
161                 }
162
163                 public string Basename {
164                         get {
165                                 if (TypeArguments != null)
166                                         return MakeName (Name, TypeArguments);
167                                 return Name;
168                         }
169                 }
170
171                 public string GetSignatureForError ()
172                 {
173                         string append = TypeArguments == null ? "" : "<" + TypeArguments.GetSignatureForError () + ">";
174                         if (Left == null)
175                                 return Name + append;
176                         string connect = is_double_colon ? "::" : ".";
177                         return Left.GetSignatureForError () + connect + Name + append;
178                 }
179
180                 public override bool Equals (object other)
181                 {
182                         return Equals (other as MemberName);
183                 }
184
185                 public bool Equals (MemberName other)
186                 {
187                         if (this == other)
188                                 return true;
189                         if (other == null || Name != other.Name)
190                                 return false;
191                         if (is_double_colon != other.is_double_colon)
192                                 return false;
193
194                         if ((TypeArguments != null) &&
195                             (other.TypeArguments == null || TypeArguments.Count != other.TypeArguments.Count))
196                                 return false;
197
198                         if ((TypeArguments == null) && (other.TypeArguments != null))
199                                 return false;
200
201                         if (Left == null)
202                                 return other.Left == null;
203
204                         return Left.Equals (other.Left);
205                 }
206
207                 public override int GetHashCode ()
208                 {
209                         int hash = Name.GetHashCode ();
210                         for (MemberName n = Left; n != null; n = n.Left)
211                                 hash ^= n.Name.GetHashCode ();
212                         if (is_double_colon)
213                                 hash ^= 0xbadc01d;
214
215                         if (TypeArguments != null)
216                                 hash ^= TypeArguments.Count << 5;
217
218                         return hash & 0x7FFFFFFF;
219                 }
220
221                 public int CountTypeArguments {
222                         get {
223                                 if (TypeArguments != null)
224                                         return TypeArguments.Count;
225                                 else if (Left != null)
226                                         return Left.CountTypeArguments; 
227                                 else
228                                         return 0;
229                         }
230                 }
231
232                 public static string MakeName (string name, TypeArguments args)
233                 {
234                         if (args == null)
235                                 return name;
236
237                         return name + "`" + args.Count;
238                 }
239
240                 public static string MakeName (string name, int count)
241                 {
242                         return name + "`" + count;
243                 }
244         }
245
246         public class SimpleMemberName
247         {
248                 public string Value;
249                 public Location Location;
250
251                 public SimpleMemberName (string name, Location loc)
252                 {
253                         this.Value = name;
254                         this.Location = loc;
255                 }
256         }
257
258         /// <summary>
259         ///   Base representation for members.  This is used to keep track
260         ///   of Name, Location and Modifier flags, and handling Attributes.
261         /// </summary>
262         [System.Diagnostics.DebuggerDisplay ("{GetSignatureForError()}")]
263         public abstract class MemberCore : Attributable, IMemberContext, IMemberDefinition
264         {
265                 /// <summary>
266                 ///   Public name
267                 /// </summary>
268
269                 protected string cached_name;
270                 // TODO: Remove in favor of MemberName
271                 public string Name {
272                         get {
273                                 if (cached_name == null)
274                                         cached_name = MemberName.GetName (!(this is GenericMethod) && !(this is Method));
275                                 return cached_name;
276                         }
277                 }
278
279                 string IMemberDefinition.Name {
280                         get {
281                                 return member_name.Name;
282                         }
283                 }
284
285                 // Is not readonly because of IndexerName attribute
286                 private MemberName member_name;
287                 public MemberName MemberName {
288                         get { return member_name; }
289                 }
290
291                 /// <summary>
292                 ///   Modifier flags that the user specified in the source code
293                 /// </summary>
294                 private Modifiers mod_flags;
295                 public Modifiers ModFlags {
296                         set {
297                                 mod_flags = value;
298                                 if ((value & Modifiers.COMPILER_GENERATED) != 0)
299                                         caching_flags = Flags.IsUsed | Flags.IsAssigned;
300                         }
301                         get {
302                                 return mod_flags;
303                         }
304                 }
305
306                 public virtual ModuleContainer Module {
307                         get {
308                                 return Parent.Module;
309                         }
310                 }
311
312                 public /*readonly*/ TypeContainer Parent;
313
314                 /// <summary>
315                 ///   Location where this declaration happens
316                 /// </summary>
317                 public Location Location {
318                         get { return member_name.Location; }
319                 }
320
321                 /// <summary>
322                 ///   XML documentation comment
323                 /// </summary>
324                 protected string comment;
325
326                 /// <summary>
327                 ///   Represents header string for documentation comment 
328                 ///   for each member types.
329                 /// </summary>
330                 public abstract string DocCommentHeader { get; }
331
332                 [Flags]
333                 public enum Flags {
334                         Obsolete_Undetected = 1,                // Obsolete attribute has not been detected yet
335                         Obsolete = 1 << 1,                      // Type has obsolete attribute
336                         ClsCompliance_Undetected = 1 << 2,      // CLS Compliance has not been detected yet
337                         ClsCompliant = 1 << 3,                  // Type is CLS Compliant
338                         CloseTypeCreated = 1 << 4,              // Tracks whether we have Closed the type
339                         HasCompliantAttribute_Undetected = 1 << 5,      // Presence of CLSCompliantAttribute has not been detected
340                         HasClsCompliantAttribute = 1 << 6,                      // Type has CLSCompliantAttribute
341                         ClsCompliantAttributeFalse = 1 << 7,                    // Member has CLSCompliant(false)
342                         Excluded_Undetected = 1 << 8,           // Conditional attribute has not been detected yet
343                         Excluded = 1 << 9,                                      // Method is conditional
344                         MethodOverloadsExist = 1 << 10,         // Test for duplication must be performed
345                         IsUsed = 1 << 11,
346                         IsAssigned = 1 << 12,                           // Field is assigned
347                         HasExplicitLayout       = 1 << 13,
348                         PartialDefinitionExists = 1 << 14,      // Set when corresponding partial method definition exists
349                         HasStructLayout         = 1 << 15                       // Has StructLayoutAttribute
350                 }
351
352                 /// <summary>
353                 ///   MemberCore flags at first detected then cached
354                 /// </summary>
355                 internal Flags caching_flags;
356
357                 public MemberCore (DeclSpace parent, MemberName name, Attributes attrs)
358                 {
359                         this.Parent = parent as TypeContainer;
360                         member_name = name;
361                         caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected;
362                         AddAttributes (attrs, this);
363                 }
364
365                 protected virtual void SetMemberName (MemberName new_name)
366                 {
367                         member_name = new_name;
368                         cached_name = null;
369                 }
370
371                 protected bool CheckAbstractAndExtern (bool has_block)
372                 {
373                         if (Parent.PartialContainer.Kind == MemberKind.Interface)
374                                 return true;
375
376                         if (has_block) {
377                                 if ((ModFlags & Modifiers.EXTERN) != 0) {
378                                         Report.Error (179, Location, "`{0}' cannot declare a body because it is marked extern",
379                                                 GetSignatureForError ());
380                                         return false;
381                                 }
382
383                                 if ((ModFlags & Modifiers.ABSTRACT) != 0) {
384                                         Report.Error (500, Location, "`{0}' cannot declare a body because it is marked abstract",
385                                                 GetSignatureForError ());
386                                         return false;
387                                 }
388                         } else {
389                                 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN | Modifiers.PARTIAL)) == 0 && !(Parent is Delegate)) {
390                                         if (Compiler.Settings.Version >= LanguageVersion.V_3) {
391                                                 Property.PropertyMethod pm = this as Property.PropertyMethod;
392                                                 if (pm is Indexer.GetIndexerMethod || pm is Indexer.SetIndexerMethod)
393                                                         pm = null;
394
395                                                 if (pm != null && pm.Property.AccessorSecond == null) {
396                                                         Report.Error (840, Location,
397                                                                 "`{0}' must have a body because it is not marked abstract or extern. The property can be automatically implemented when you define both accessors",
398                                                                 GetSignatureForError ());
399                                                         return false;
400                                                 }
401                                         }
402
403                                         Report.Error (501, Location, "`{0}' must have a body because it is not marked abstract, extern, or partial",
404                                                       GetSignatureForError ());
405                                         return false;
406                                 }
407                         }
408
409                         return true;
410                 }
411
412                 protected void CheckProtectedModifier ()
413                 {
414                         if ((ModFlags & Modifiers.PROTECTED) == 0)
415                                 return;
416
417                         if (Parent.PartialContainer.Kind == MemberKind.Struct) {
418                                 Report.Error (666, Location, "`{0}': Structs cannot contain protected members",
419                                         GetSignatureForError ());
420                                 return;
421                         }
422
423                         if ((Parent.ModFlags & Modifiers.STATIC) != 0) {
424                                 Report.Error (1057, Location, "`{0}': Static classes cannot contain protected members",
425                                         GetSignatureForError ());
426                                 return;
427                         }
428
429                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.OVERRIDE) == 0 &&
430                                 !(this is Destructor)) {
431                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class",
432                                         GetSignatureForError ());
433                                 return;
434                         }
435                 }
436
437                 public abstract bool Define ();
438
439                 public virtual string DocComment {
440                         get {
441                                 return comment;
442                         }
443                         set {
444                                 comment = value;
445                         }
446                 }
447
448                 // 
449                 // Returns full member name for error message
450                 //
451                 public virtual string GetSignatureForError ()
452                 {
453                         if (Parent == null || Parent.Parent == null)
454                                 return member_name.GetSignatureForError ();
455
456                         return Parent.GetSignatureForError () + "." + member_name.GetSignatureForError ();
457                 }
458
459                 /// <summary>
460                 /// Base Emit method. This is also entry point for CLS-Compliant verification.
461                 /// </summary>
462                 public virtual void Emit ()
463                 {
464                         if (!Compiler.Settings.VerifyClsCompliance)
465                                 return;
466
467                         VerifyClsCompliance ();
468                 }
469
470                 public bool IsCompilerGenerated {
471                         get     {
472                                 if ((mod_flags & Modifiers.COMPILER_GENERATED) != 0)
473                                         return true;
474
475                                 return Parent == null ? false : Parent.IsCompilerGenerated;
476                         }
477                 }
478
479                 public bool IsImported {
480                         get {
481                                 return false;
482                         }
483                 }
484
485                 public virtual bool IsUsed {
486                         get {
487                                 return (caching_flags & Flags.IsUsed) != 0;
488                         }
489                 }
490
491                 protected Report Report {
492                         get {
493                                 return Compiler.Report;
494                         }
495                 }
496
497                 public void SetIsUsed ()
498                 {
499                         caching_flags |= Flags.IsUsed;
500                 }
501
502                 public void SetIsAssigned ()
503                 {
504                         caching_flags |= Flags.IsAssigned;
505                 }
506
507                 /// <summary>
508                 /// Returns instance of ObsoleteAttribute for this MemberCore
509                 /// </summary>
510                 public virtual ObsoleteAttribute GetAttributeObsolete ()
511                 {
512                         if ((caching_flags & (Flags.Obsolete_Undetected | Flags.Obsolete)) == 0)
513                                 return null;
514
515                         caching_flags &= ~Flags.Obsolete_Undetected;
516
517                         if (OptAttributes == null)
518                                 return null;
519
520                         Attribute obsolete_attr = OptAttributes.Search (Module.PredefinedAttributes.Obsolete);
521                         if (obsolete_attr == null)
522                                 return null;
523
524                         caching_flags |= Flags.Obsolete;
525
526                         ObsoleteAttribute obsolete = obsolete_attr.GetObsoleteAttribute ();
527                         if (obsolete == null)
528                                 return null;
529
530                         return obsolete;
531                 }
532
533                 /// <summary>
534                 /// Checks for ObsoleteAttribute presence. It's used for testing of all non-types elements
535                 /// </summary>
536                 public virtual void CheckObsoleteness (Location loc)
537                 {
538                         ObsoleteAttribute oa = GetAttributeObsolete ();
539                         if (oa != null)
540                                 AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, Report);
541                 }
542
543                 //
544                 // Checks whether the type P is as accessible as this member
545                 //
546                 public bool IsAccessibleAs (TypeSpec p)
547                 {
548                         //
549                         // if M is private, its accessibility is the same as this declspace.
550                         // we already know that P is accessible to T before this method, so we
551                         // may return true.
552                         //
553                         if ((mod_flags & Modifiers.PRIVATE) != 0)
554                                 return true;
555
556                         while (TypeManager.HasElementType (p))
557                                 p = TypeManager.GetElementType (p);
558
559                         if (p.IsGenericParameter)
560                                 return true;
561
562                         for (TypeSpec p_parent; p != null; p = p_parent) {
563                                 p_parent = p.DeclaringType;
564
565                                 if (p.IsGeneric) {
566                                         foreach (TypeSpec t in p.TypeArguments) {
567                                                 if (!IsAccessibleAs (t))
568                                                         return false;
569                                         }
570                                 }
571
572                                 var pAccess = p.Modifiers & Modifiers.AccessibilityMask;
573                                 if (pAccess == Modifiers.PUBLIC)
574                                         continue;
575
576                                 bool same_access_restrictions = false;
577                                 for (MemberCore mc = this; !same_access_restrictions && mc != null && mc.Parent != null; mc = mc.Parent) {
578                                         var al = mc.ModFlags & Modifiers.AccessibilityMask;
579                                         switch (pAccess) {
580                                         case Modifiers.INTERNAL:
581                                                 if (al == Modifiers.PRIVATE || al == Modifiers.INTERNAL)
582                                                         same_access_restrictions = p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly);
583                                                 
584                                                 break;
585
586                                         case Modifiers.PROTECTED:
587                                                 if (al == Modifiers.PROTECTED) {
588                                                         same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent);
589                                                         break;
590                                                 }
591
592                                                 if (al == Modifiers.PRIVATE) {
593                                                         //
594                                                         // When type is private and any of its parents derives from
595                                                         // protected type then the type is accessible
596                                                         //
597                                                         while (mc.Parent != null) {
598                                                                 if (mc.Parent.IsBaseTypeDefinition (p_parent))
599                                                                         same_access_restrictions = true;
600                                                                 mc = mc.Parent; 
601                                                         }
602                                                 }
603                                                 
604                                                 break;
605
606                                         case Modifiers.PROTECTED | Modifiers.INTERNAL:
607                                                 if (al == Modifiers.INTERNAL)
608                                                         same_access_restrictions = p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly);
609                                                 else if (al == (Modifiers.PROTECTED | Modifiers.INTERNAL))
610                                                         same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent) && p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly);
611                                                 else
612                                                         goto case Modifiers.PROTECTED;
613
614                                                 break;
615
616                                         case Modifiers.PRIVATE:
617                                                 //
618                                                 // Both are private and share same parent
619                                                 //
620                                                 if (al == Modifiers.PRIVATE) {
621                                                         var decl = mc.Parent;
622                                                         do {
623                                                                 same_access_restrictions = decl.CurrentType == p_parent;
624                                                         } while (!same_access_restrictions && !decl.IsTopLevel && (decl = decl.Parent) != null);
625                                                 }
626                                                 
627                                                 break;
628                                                 
629                                         default:
630                                                 throw new InternalErrorException (al.ToString ());
631                                         }
632                                 }
633                                 
634                                 if (!same_access_restrictions)
635                                         return false;
636                         }
637
638                         return true;
639                 }
640
641                 /// <summary>
642                 /// Analyze whether CLS-Compliant verification must be execute for this MemberCore.
643                 /// </summary>
644                 public override bool IsClsComplianceRequired ()
645                 {
646                         if ((caching_flags & Flags.ClsCompliance_Undetected) == 0)
647                                 return (caching_flags & Flags.ClsCompliant) != 0;
648
649                         caching_flags &= ~Flags.ClsCompliance_Undetected;
650
651                         if (HasClsCompliantAttribute) {
652                                 if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0)
653                                         return false;
654
655                                 caching_flags |= Flags.ClsCompliant;
656                                 return true;
657                         }
658
659                         if (Parent.PartialContainer.IsClsComplianceRequired ()) {
660                                 caching_flags |= Flags.ClsCompliant;
661                                 return true;
662                         }
663
664                         return false;
665                 }
666
667                 public virtual string[] ConditionalConditions ()
668                 {
669                         return null;
670                 }
671
672                 /// <summary>
673                 /// Returns true when MemberCore is exposed from assembly.
674                 /// </summary>
675                 public bool IsExposedFromAssembly ()
676                 {
677                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
678                                 return false;
679                         
680                         DeclSpace parentContainer = Parent.PartialContainer;
681                         while (parentContainer != null && parentContainer.ModFlags != 0) {
682                                 if ((parentContainer.ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
683                                         return false;
684                                 parentContainer = parentContainer.Parent;
685                         }
686                         return true;
687                 }
688
689                 public virtual IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceContainer scope)
690                 {
691                         return Parent.LookupExtensionMethod (extensionType, name, arity, ref scope);
692                 }
693
694                 public virtual FullNamedExpression LookupNamespaceAlias (string name)
695                 {
696                         return Parent.NamespaceEntry.LookupNamespaceAlias (name);
697                 }
698
699                 public virtual FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
700                 {
701                         return Parent.LookupNamespaceOrType (name, arity, mode, loc);
702                 }
703
704                 /// <summary>
705                 /// Goes through class hierarchy and gets value of first found CLSCompliantAttribute.
706                 /// If no is attribute exists then assembly CLSCompliantAttribute is returned.
707                 /// </summary>
708                 public bool? CLSAttributeValue {
709                         get {
710                                 if ((caching_flags & Flags.HasCompliantAttribute_Undetected) == 0) {
711                                         if ((caching_flags & Flags.HasClsCompliantAttribute) == 0)
712                                                 return null;
713
714                                         return (caching_flags & Flags.ClsCompliantAttributeFalse) == 0;
715                                 }
716
717                                 caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
718
719                                 if (OptAttributes != null) {
720                                         Attribute cls_attribute = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant);
721                                         if (cls_attribute != null) {
722                                                 caching_flags |= Flags.HasClsCompliantAttribute;
723                                                 if (cls_attribute.GetClsCompliantAttributeValue ())
724                                                         return true;
725
726                                                 caching_flags |= Flags.ClsCompliantAttributeFalse;
727                                                 return false;
728                                         }
729                                 }
730
731                                 return null;
732                         }
733                 }
734
735                 /// <summary>
736                 /// Returns true if MemberCore is explicitly marked with CLSCompliantAttribute
737                 /// </summary>
738                 protected bool HasClsCompliantAttribute {
739                         get {
740                                 return CLSAttributeValue.HasValue;
741                         }
742                 }
743
744                 /// <summary>
745                 /// Returns true when a member supports multiple overloads (methods, indexers, etc)
746                 /// </summary>
747                 public virtual bool EnableOverloadChecks (MemberCore overload)
748                 {
749                         return false;
750                 }
751
752                 /// <summary>
753                 /// The main virtual method for CLS-Compliant verifications.
754                 /// The method returns true if member is CLS-Compliant and false if member is not
755                 /// CLS-Compliant which means that CLS-Compliant tests are not necessary. A descendants override it
756                 /// and add their extra verifications.
757                 /// </summary>
758                 protected virtual bool VerifyClsCompliance ()
759                 {
760                         if (HasClsCompliantAttribute) {
761                                 if (!Module.DeclaringAssembly.HasCLSCompliantAttribute) {
762                                         Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant);
763                                         if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) {
764                                                 Report.Warning (3021, 2, a.Location,
765                                                         "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant",
766                                                         GetSignatureForError ());
767                                         } else {
768                                                 Report.Warning (3014, 1, a.Location,
769                                                         "`{0}' cannot be marked as CLS-compliant because the assembly is not marked as CLS-compliant",
770                                                         GetSignatureForError ());
771                                         }
772                                         return false;
773                                 }
774
775                                 if (!IsExposedFromAssembly ()) {
776                                         Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant);
777                                         Report.Warning (3019, 2, a.Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ());
778                                         return false;
779                                 }
780
781                                 if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) {
782                                         if (Parent.Kind == MemberKind.Interface && Parent.IsClsComplianceRequired ()) {
783                                                 Report.Warning (3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
784                                         } else if (Parent.Kind == MemberKind.Class && (ModFlags & Modifiers.ABSTRACT) != 0 && Parent.IsClsComplianceRequired ()) {
785                                                 Report.Warning (3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
786                                         }
787
788                                         return false;
789                                 }
790
791                                 if (Parent.Parent != null && !Parent.IsClsComplianceRequired ()) {
792                                         Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant);
793                                         Report.Warning (3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'",
794                                                 GetSignatureForError (), Parent.GetSignatureForError ());
795                                         return false;
796                                 }
797                         } else {
798                                 if (!IsExposedFromAssembly ())
799                                         return false;
800
801                                 if (!Parent.PartialContainer.IsClsComplianceRequired ())
802                                         return false;
803                         }
804
805                         if (member_name.Name [0] == '_') {
806                                 Report.Warning (3008, 1, Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError () );
807                         }
808
809                         return true;
810                 }
811
812                 //
813                 // Returns a string that represents the signature for this 
814                 // member which should be used in XML documentation.
815                 //
816                 public abstract string GetSignatureForDocumentation ();
817
818                 //
819                 // Generates xml doc comments (if any), and if required,
820                 // handle warning report.
821                 //
822                 internal virtual void GenerateDocComment (DocumentationBuilder builder)
823                 {
824                         if (DocComment == null) {
825                                 if (IsExposedFromAssembly ()) {
826                                         Constructor c = this as Constructor;
827                                         if (c == null || !c.IsDefault ())
828                                                 Report.Warning (1591, 4, Location,
829                                                         "Missing XML comment for publicly visible type or member `{0}'", GetSignatureForError ());
830                                 }
831
832                                 return;
833                         }
834
835                         try {
836                                 builder.GenerateDocumentationForMember (this);
837                         } catch (Exception e) {
838                                 throw new InternalErrorException (this, e);
839                         }
840                 }
841
842                 #region IMemberContext Members
843
844                 public virtual CompilerContext Compiler {
845                         get { return Parent.Compiler; }
846                 }
847
848                 public virtual TypeSpec CurrentType {
849                         get { return Parent.CurrentType; }
850                 }
851
852                 public MemberCore CurrentMemberDefinition {
853                         get { return this; }
854                 }
855
856                 public virtual TypeParameter[] CurrentTypeParameters {
857                         get { return null; }
858                 }
859
860                 public bool IsObsolete {
861                         get {
862                                 if (GetAttributeObsolete () != null)
863                                         return true;
864
865                                 return Parent == null ? false : Parent.IsObsolete;
866                         }
867                 }
868
869                 public bool IsUnsafe {
870                         get {
871                                 if ((ModFlags & Modifiers.UNSAFE) != 0)
872                                         return true;
873
874                                 return Parent == null ? false : Parent.IsUnsafe;
875                         }
876                 }
877
878                 public bool IsStatic {
879                         get {
880                                 return (ModFlags & Modifiers.STATIC) != 0;
881                         }
882                 }
883
884                 #endregion
885         }
886
887         //
888         // Base member specification. A member specification contains
889         // member details which can alter in the context (e.g. generic instances)
890         //
891         public abstract class MemberSpec
892         {
893                 [Flags]
894                 public enum StateFlags
895                 {
896                         Obsolete_Undetected = 1,        // Obsolete attribute has not been detected yet
897                         Obsolete = 1 << 1,                      // Member has obsolete attribute
898                         CLSCompliant_Undetected = 1 << 2,       // CLSCompliant attribute has not been detected yet
899                         CLSCompliant = 1 << 3,          // Member is CLS Compliant
900                         MissingDependency_Undetected = 1 << 4,
901                         MissingDependency = 1 << 5,
902                         HasDynamicElement = 1 << 6,
903                         ConstraintsChecked = 1 << 7,
904
905                         IsAccessor = 1 << 9,            // Method is an accessor
906                         IsGeneric = 1 << 10,            // Member contains type arguments
907
908                         PendingMetaInflate = 1 << 12,
909                         PendingMakeMethod = 1 << 13,
910                         PendingMemberCacheMembers = 1 << 14,
911                         PendingBaseTypeInflate = 1 << 15,
912                         InterfacesExpanded = 1 << 16,
913                         IsNotCSharpCompatible = 1 << 17,
914                         SpecialRuntimeType = 1 << 18,
915                         InflatedExpressionType = 1 << 19,
916                         InflatedNullableType = 1 << 20,
917                         GenericIterateInterface = 1 << 21,
918                         GenericTask = 1 << 22
919                 }
920
921                 protected Modifiers modifiers;
922                 public StateFlags state;
923                 protected IMemberDefinition definition;
924                 public readonly MemberKind Kind;
925                 protected TypeSpec declaringType;
926
927 #if DEBUG
928                 static int counter;
929                 public int ID = counter++;
930 #endif
931
932                 protected MemberSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition definition, Modifiers modifiers)
933                 {
934                         this.Kind = kind;
935                         this.declaringType = declaringType;
936                         this.definition = definition;
937                         this.modifiers = modifiers;
938
939                         state = StateFlags.Obsolete_Undetected | StateFlags.CLSCompliant_Undetected | StateFlags.MissingDependency_Undetected;
940                 }
941
942                 #region Properties
943
944                 public virtual int Arity {
945                         get {
946                                 return 0;
947                         }
948                 }
949
950                 public TypeSpec DeclaringType {
951                         get {
952                                 return declaringType;
953                         }
954                         set {
955                                 declaringType = value;
956                         }
957                 }
958
959                 public IMemberDefinition MemberDefinition {
960                         get {
961                                 return definition;
962                         }
963                 }
964
965                 public Modifiers Modifiers {
966                         get {
967                                 return modifiers;
968                         }
969                         set {
970                                 modifiers = value;
971                         }
972                 }
973                 
974                 public virtual string Name {
975                         get {
976                                 return definition.Name;
977                         }
978                 }
979
980                 public bool IsAbstract {
981                         get { return (modifiers & Modifiers.ABSTRACT) != 0; }
982                 }
983
984                 public bool IsAccessor {
985                         get {
986                                 return (state & StateFlags.IsAccessor) != 0;
987                         }
988                         set {
989                                 state = value ? state | StateFlags.IsAccessor : state & ~StateFlags.IsAccessor;
990                         }
991                 }
992
993                 //
994                 // Return true when this member is a generic in C# terms
995                 // A nested non-generic type of generic type will return false
996                 //
997                 public bool IsGeneric {
998                         get {
999                                 return (state & StateFlags.IsGeneric) != 0;
1000                         }
1001                         set {
1002                                 state = value ? state | StateFlags.IsGeneric : state & ~StateFlags.IsGeneric;
1003                         }
1004                 }
1005
1006                 //
1007                 // Returns true for imported members which are not compatible with C# language
1008                 //
1009                 public bool IsNotCSharpCompatible {
1010                         get {
1011                                 return (state & StateFlags.IsNotCSharpCompatible) != 0;
1012                         }
1013                         set {
1014                                 state = value ? state | StateFlags.IsNotCSharpCompatible : state & ~StateFlags.IsNotCSharpCompatible;
1015                         }
1016                 }
1017
1018                 public bool IsPrivate {
1019                         get { return (modifiers & Modifiers.PRIVATE) != 0; }
1020                 }
1021
1022                 public bool IsPublic {
1023                         get { return (modifiers & Modifiers.PUBLIC) != 0; }
1024                 }
1025
1026                 public bool IsStatic {
1027                         get { 
1028                                 return (modifiers & Modifiers.STATIC) != 0;
1029                         }
1030                 }
1031
1032                 #endregion
1033
1034                 public virtual ObsoleteAttribute GetAttributeObsolete ()
1035                 {
1036                         if ((state & (StateFlags.Obsolete | StateFlags.Obsolete_Undetected)) == 0)
1037                                 return null;
1038
1039                         state &= ~StateFlags.Obsolete_Undetected;
1040
1041                         var oa = definition.GetAttributeObsolete ();
1042                         if (oa != null)
1043                                 state |= StateFlags.Obsolete;
1044
1045                         return oa;
1046                 }
1047
1048                 //
1049                 // Returns a list of missing dependencies of this member. The list
1050                 // will contain types only but it can have numerous values for members
1051                 // like methods where both return type and all parameters are checked
1052                 //
1053                 public List<TypeSpec> GetMissingDependencies ()
1054                 {
1055                         if ((state & (StateFlags.MissingDependency | StateFlags.MissingDependency_Undetected)) == 0)
1056                                 return null;
1057
1058                         state &= ~StateFlags.MissingDependency_Undetected;
1059
1060                         var imported = definition as ImportedDefinition;
1061                         List<TypeSpec> missing;
1062                         if (imported != null) {
1063                                 missing = ResolveMissingDependencies ();
1064                         } else if (this is ElementTypeSpec) {
1065                                 missing = ((ElementTypeSpec) this).Element.GetMissingDependencies ();
1066                         } else {
1067                                 missing = null;
1068                         }
1069
1070                         if (missing != null) {
1071                                 state |= StateFlags.MissingDependency;
1072                         }
1073
1074                         return missing;
1075                 }
1076
1077                 public abstract List<TypeSpec> ResolveMissingDependencies ();
1078
1079                 protected virtual bool IsNotCLSCompliant (out bool attrValue)
1080                 {
1081                         var cls = MemberDefinition.CLSAttributeValue;
1082                         attrValue = cls ?? false;
1083                         return cls == false;
1084                 }
1085
1086                 public virtual string GetSignatureForDocumentation ()
1087                 {
1088                         return DeclaringType.GetSignatureForDocumentation () + "." + Name;
1089                 }
1090
1091                 public virtual string GetSignatureForError ()
1092                 {
1093                         var bf = MemberDefinition as Property.BackingField;
1094                         var name = bf == null ? Name : bf.OriginalName;
1095                         return DeclaringType.GetSignatureForError () + "." + name;
1096                 }
1097
1098                 public virtual MemberSpec InflateMember (TypeParameterInflator inflator)
1099                 {
1100                         var inflated = (MemberSpec) MemberwiseClone ();
1101                         inflated.declaringType = inflator.TypeInstance;
1102                         if (DeclaringType.IsGenericOrParentIsGeneric)
1103                                 inflated.state |= StateFlags.PendingMetaInflate;
1104 #if DEBUG
1105                         inflated.ID += 1000000;
1106 #endif
1107                         return inflated;
1108                 }
1109
1110                 //
1111                 // Is this member accessible from invocation context
1112                 //
1113                 public bool IsAccessible (IMemberContext ctx)
1114                 {
1115                         var ma = Modifiers & Modifiers.AccessibilityMask;
1116                         if (ma == Modifiers.PUBLIC)
1117                                 return true;
1118
1119                         var parentType = /* this as TypeSpec ?? */ DeclaringType;
1120                         var ctype = ctx.CurrentType;
1121
1122                         if (ma == Modifiers.PRIVATE) {
1123                                 if (ctype == null)
1124                                         return false;
1125                                 //
1126                                 // It's only accessible to the current class or children
1127                                 //
1128                                 if (parentType.MemberDefinition == ctype.MemberDefinition)
1129                                         return true;
1130
1131                                 return TypeManager.IsNestedChildOf (ctype, parentType.MemberDefinition);
1132                         }
1133
1134                         if ((ma & Modifiers.INTERNAL) != 0) {
1135                                 bool b;
1136                                 var assembly = ctype == null ? ctx.Module.DeclaringAssembly : ctype.MemberDefinition.DeclaringAssembly;
1137
1138                                 if (parentType == null) {
1139                                         b = ((ITypeDefinition) MemberDefinition).IsInternalAsPublic (assembly);
1140                                 } else {
1141                                         b = DeclaringType.MemberDefinition.IsInternalAsPublic (assembly);
1142                                 }
1143
1144                                 if (b || ma == Modifiers.INTERNAL)
1145                                         return b;
1146                         }
1147
1148                         //
1149                         // Checks whether `ctype' is a subclass or nested child of `parentType'.
1150                         //
1151                         while (ctype != null) {
1152                                 if (TypeManager.IsFamilyAccessible (ctype, parentType))
1153                                         return true;
1154
1155                                 // Handle nested types.
1156                                 ctype = ctype.DeclaringType;    // TODO: Untested ???
1157                         }
1158
1159                         return false;
1160                 }
1161
1162                 //
1163                 // Returns member CLS compliance based on full member hierarchy
1164                 //
1165                 public bool IsCLSCompliant ()
1166                 {
1167                         if ((state & StateFlags.CLSCompliant_Undetected) != 0) {
1168                                 state &= ~StateFlags.CLSCompliant_Undetected;
1169
1170                                 bool compliant;
1171                                 if (IsNotCLSCompliant (out compliant))
1172                                         return false;
1173
1174                                 if (!compliant) {
1175                                         if (DeclaringType != null) {
1176                                                 compliant = DeclaringType.IsCLSCompliant ();
1177                                         } else {
1178                                                 compliant = ((ITypeDefinition) MemberDefinition).DeclaringAssembly.IsCLSCompliant;
1179                                         }
1180                                 }
1181
1182                                 if (compliant)
1183                                         state |= StateFlags.CLSCompliant;
1184                         }
1185
1186                         return (state & StateFlags.CLSCompliant) != 0;
1187                 }
1188
1189                 public bool IsConditionallyExcluded (CompilerContext ctx, Location loc)
1190                 {
1191                         if ((Kind & (MemberKind.Class | MemberKind.Method)) == 0)
1192                                 return false;
1193
1194                         var conditions = MemberDefinition.ConditionalConditions ();
1195                         if (conditions == null)
1196                                 return false;
1197
1198                         foreach (var condition in conditions) {
1199                                 if (loc.CompilationUnit.IsConditionalDefined (ctx, condition))
1200                                         return false;
1201                         }
1202
1203                         return true;
1204                 }
1205
1206                 public override string ToString ()
1207                 {
1208                         return GetSignatureForError ();
1209                 }
1210         }
1211
1212         //
1213         // Member details which are same between all member
1214         // specifications
1215         //
1216         public interface IMemberDefinition
1217         {
1218                 bool? CLSAttributeValue { get; }
1219                 string Name { get; }
1220                 bool IsImported { get; }
1221
1222                 string[] ConditionalConditions ();
1223                 ObsoleteAttribute GetAttributeObsolete ();
1224                 void SetIsAssigned ();
1225                 void SetIsUsed ();
1226         }
1227
1228         public interface IParametersMember : IInterfaceMemberSpec
1229         {
1230                 AParametersCollection Parameters { get; }
1231         }
1232
1233         public interface IInterfaceMemberSpec
1234         {
1235                 TypeSpec MemberType { get; }
1236         }
1237
1238         //
1239         // Base type container declaration. It exists to handle partial types
1240         // which share same definition (PartialContainer) but have different
1241         // resolve scopes
1242         //
1243         public abstract class DeclSpace : MemberCore {
1244                 /// <summary>
1245                 ///   This points to the actual definition that is being
1246                 ///   created with System.Reflection.Emit
1247                 /// </summary>
1248                 public TypeBuilder TypeBuilder;
1249
1250                 //
1251                 // This is the namespace in which this typecontainer
1252                 // was declared.  We use this to resolve names.
1253                 //
1254                 public NamespaceContainer NamespaceEntry;
1255
1256                 public readonly string Basename;
1257                 
1258                 protected Dictionary<string, MemberCore> defined_names;
1259
1260                 public TypeContainer PartialContainer;          
1261
1262                 protected readonly bool is_generic;
1263                 readonly int count_type_params;
1264                 protected TypeParameter[] type_params;
1265                 TypeParameter[] type_param_list;
1266
1267                 //
1268                 // Whether we are Generic
1269                 //
1270                 public bool IsGeneric {
1271                         get {
1272                                 if (is_generic)
1273                                         return true;
1274                                 else if (Parent != null)
1275                                         return Parent.IsGeneric;
1276                                 else
1277                                         return false;
1278                         }
1279                 }
1280
1281                 static readonly string[] attribute_targets = new string [] { "type" };
1282
1283                 public DeclSpace (NamespaceContainer ns, DeclSpace parent, MemberName name,
1284                                   Attributes attrs)
1285                         : base (parent, name, attrs)
1286                 {
1287                         NamespaceEntry = ns;
1288                         Basename = name.Basename;
1289                         defined_names = new Dictionary<string, MemberCore> ();
1290                         PartialContainer = null;
1291                         if (name.TypeArguments != null) {
1292                                 is_generic = true;
1293                                 count_type_params = name.TypeArguments.Count;
1294                         }
1295                         if (parent != null)
1296                                 count_type_params += parent.count_type_params;
1297                 }
1298
1299                 /// <summary>
1300                 /// Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
1301                 /// </summary>
1302                 protected virtual bool AddToContainer (MemberCore symbol, string name)
1303                 {
1304                         MemberCore mc;
1305                         if (!defined_names.TryGetValue (name, out mc)) {
1306                                 defined_names.Add (name, symbol);
1307                                 return true;
1308                         }
1309
1310                         if (((mc.ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
1311                                 return true;
1312
1313                         if (symbol.EnableOverloadChecks (mc))
1314                                 return true;
1315
1316                         InterfaceMemberBase im = mc as InterfaceMemberBase;
1317                         if (im != null && im.IsExplicitImpl)
1318                                 return true;
1319
1320                         Report.SymbolRelatedToPreviousError (mc);
1321                         if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
1322                                 Error_MissingPartialModifier (symbol);
1323                                 return false;
1324                         }
1325
1326                         if (symbol is TypeParameter) {
1327                                 Report.Error (692, symbol.Location,
1328                                         "Duplicate type parameter `{0}'", symbol.GetSignatureForError ());
1329                         } else {
1330                                 Report.Error (102, symbol.Location,
1331                                         "The type `{0}' already contains a definition for `{1}'",
1332                                         GetSignatureForError (), symbol.MemberName.Name);
1333                         }
1334
1335                         return false;
1336                 }
1337
1338                 protected void RemoveFromContainer (string name)
1339                 {
1340                         defined_names.Remove (name);
1341                 }
1342                 
1343                 /// <summary>
1344                 ///   Returns the MemberCore associated with a given name in the declaration
1345                 ///   space. It doesn't return method based symbols !!
1346                 /// </summary>
1347                 /// 
1348                 public MemberCore GetDefinition (string name)
1349                 {
1350                         MemberCore mc = null;
1351                         defined_names.TryGetValue (name, out mc);
1352                         return mc;
1353                 }
1354         
1355                 // 
1356                 // root_types contains all the types.  All TopLevel types
1357                 // hence have a parent that points to `root_types', that is
1358                 // why there is a non-obvious test down here.
1359                 //
1360                 public bool IsTopLevel {
1361                         get { return (Parent != null && Parent.Parent == null); }
1362                 }
1363
1364                 public virtual bool IsUnmanagedType ()
1365                 {
1366                         return false;
1367                 }
1368
1369                 protected abstract TypeAttributes TypeAttr { get; }
1370
1371                 /// <remarks>
1372                 ///  Should be overriten by the appropriate declaration space
1373                 /// </remarks>
1374                 public abstract void DefineType ();
1375
1376                 protected void Error_MissingPartialModifier (MemberCore type)
1377                 {
1378                         Report.Error (260, type.Location,
1379                                 "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
1380                                 type.GetSignatureForError ());
1381                 }
1382
1383                 public override string GetSignatureForDocumentation ()
1384                 {
1385                         return Name;
1386                 }
1387
1388                 public override string GetSignatureForError ()
1389                 {
1390                         return MemberName.GetSignatureForError ();
1391                 }
1392                 
1393                 TypeParameter[] initialize_type_params ()
1394                 {
1395                         if (type_param_list != null)
1396                                 return type_param_list;
1397
1398                         DeclSpace the_parent = Parent;
1399                         if (this is GenericMethod)
1400                                 the_parent = null;
1401
1402                         var list = new List<TypeParameter> ();
1403                         if (the_parent != null && the_parent.IsGeneric) {
1404                                 // FIXME: move generics info out of DeclSpace
1405                                 TypeParameter[] parent_params = the_parent.TypeParameters;
1406                                 list.AddRange (parent_params);
1407                         }
1408  
1409                         int count = type_params != null ? type_params.Length : 0;
1410                         for (int i = 0; i < count; i++) {
1411                                 TypeParameter param = type_params [i];
1412                                 list.Add (param);
1413                                 if (Parent.CurrentTypeParameters != null) {
1414                                         foreach (TypeParameter tp in Parent.CurrentTypeParameters) {
1415                                                 if (tp.Name != param.Name)                              
1416                                                         continue;
1417
1418                                                 Report.SymbolRelatedToPreviousError (tp.Location, null);
1419                                                 Report.Warning (693, 3, param.Location,
1420                                                         "Type parameter `{0}' has the same name as the type parameter from outer type `{1}'",
1421                                                         param.Name, Parent.GetSignatureForError ());
1422                                         }
1423                                 }
1424                         }
1425
1426                         type_param_list = new TypeParameter [list.Count];
1427                         list.CopyTo (type_param_list, 0);
1428                         return type_param_list;
1429                 }
1430
1431                 public virtual void SetParameterInfo (List<Constraints> constraints_list)
1432                 {
1433                         if (!is_generic) {
1434                                 if (constraints_list != null) {
1435                                         Report.Error (
1436                                                 80, Location, "Constraints are not allowed " +
1437                                                 "on non-generic declarations");
1438                                 }
1439
1440                                 return;
1441                         }
1442
1443                         TypeParameterName[] names = MemberName.TypeArguments.GetDeclarations ();
1444                         type_params = new TypeParameter [names.Length];
1445
1446                         //
1447                         // Register all the names
1448                         //
1449                         for (int i = 0; i < type_params.Length; i++) {
1450                                 TypeParameterName name = names [i];
1451
1452                                 Constraints constraints = null;
1453                                 if (constraints_list != null) {
1454                                         int total = constraints_list.Count;
1455                                         for (int ii = 0; ii < total; ++ii) {
1456                                                 Constraints constraints_at = (Constraints)constraints_list[ii];
1457                                                 // TODO: it is used by iterators only
1458                                                 if (constraints_at == null) {
1459                                                         constraints_list.RemoveAt (ii);
1460                                                         --total;
1461                                                         continue;
1462                                                 }
1463                                                 if (constraints_at.TypeParameter.Value == name.Name) {
1464                                                         constraints = constraints_at;
1465                                                         constraints_list.RemoveAt(ii);
1466                                                         break;
1467                                                 }
1468                                         }
1469                                 }
1470
1471                                 Variance variance = name.Variance;
1472                                 if (name.Variance != Variance.None && !(this is Delegate || this is Interface)) {
1473                                         Report.Error (1960, name.Location, "Variant type parameters can only be used with interfaces and delegates");
1474                                         variance = Variance.None;
1475                                 }
1476
1477                                 type_params [i] = new TypeParameter (
1478                                         Parent, i, new MemberName (name.Name, Location), constraints, name.OptAttributes, variance);
1479
1480                                 AddToContainer (type_params [i], name.Name);
1481                         }
1482
1483                         if (constraints_list != null && constraints_list.Count > 0) {
1484                                 foreach (Constraints constraint in constraints_list) {
1485                                         Report.Error(699, constraint.Location, "`{0}': A constraint references nonexistent type parameter `{1}'", 
1486                                                 GetSignatureForError (), constraint.TypeParameter.Value);
1487                                 }
1488                         }
1489                 }
1490
1491                 protected TypeParameter[] TypeParameters {
1492                         get {
1493                                 if (!IsGeneric)
1494                                         throw new InvalidOperationException ();
1495                                 if ((PartialContainer != null) && (PartialContainer != this))
1496                                         return PartialContainer.TypeParameters;
1497                                 if (type_param_list == null)
1498                                         initialize_type_params ();
1499
1500                                 return type_param_list;
1501                         }
1502                 }
1503
1504                 public int CountTypeParameters {
1505                         get {
1506                                 return count_type_params;
1507                         }
1508                 }
1509
1510                 public override string[] ValidAttributeTargets {
1511                         get { return attribute_targets; }
1512                 }
1513
1514                 protected override bool VerifyClsCompliance ()
1515                 {
1516                         if (!base.VerifyClsCompliance ()) {
1517                                 return false;
1518                         }
1519
1520                         if (type_params != null) {
1521                                 foreach (TypeParameter tp in type_params) {
1522                                         tp.VerifyClsCompliance ();
1523                                 }
1524                         }
1525
1526                         return true;
1527                 }
1528         }
1529 }