Actually set the `class' and `struct' constraint on the GenericTypeParameterBuilder.
[mono.git] / mcs / gmcs / generic.cs
1 //
2 // generic.cs: Support classes for generics
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) 2003 Ximian, Inc.
8 //
9 using System;
10 using System.Reflection;
11 using System.Reflection.Emit;
12 using System.Globalization;
13 using System.Collections;
14 using System.Text;
15         
16 namespace Mono.CSharp {
17
18         public enum SpecialConstraint
19         {
20                 Constructor,
21                 ReferenceType,
22                 ValueType
23         }
24
25         //
26         // Tracks the constraints for a type parameter
27         //
28         public class Constraints : GenericConstraints {
29                 string name;
30                 ArrayList constraints;
31                 Location loc;
32                 
33                 //
34                 // name is the identifier, constraints is an arraylist of
35                 // Expressions (with types) or `true' for the constructor constraint.
36                 // 
37                 public Constraints (string name, ArrayList constraints,
38                                     Location loc)
39                 {
40                         this.name = name;
41                         this.constraints = constraints;
42                         this.loc = loc;
43                 }
44
45                 public string TypeParameter {
46                         get {
47                                 return name;
48                         }
49                 }
50
51                 bool has_ctor_constraint;
52                 bool has_reference_type;
53                 bool has_value_type;
54                 TypeExpr class_constraint;
55                 ArrayList iface_constraints;
56                 int num_constraints, first_constraint;
57                 Type class_constraint_type;
58                 Type[] iface_constraint_types;
59
60                 public bool HasConstructorConstraint {
61                         get { return has_ctor_constraint; }
62                 }
63
64                 public bool Resolve (DeclSpace ds)
65                 {
66                         iface_constraints = new ArrayList ();
67
68                         foreach (object obj in constraints) {
69                                 if (has_ctor_constraint) {
70                                         Report.Error (401, loc,
71                                                       "The new() constraint must be last.");
72                                         return false;
73                                 }
74
75                                 if (obj is SpecialConstraint) {
76                                         SpecialConstraint sc = (SpecialConstraint) obj;
77
78                                         if (sc == SpecialConstraint.Constructor) {
79                                                 if (!has_value_type) {
80                                                         has_ctor_constraint = true;
81                                                         continue;
82                                                 }
83
84                                                 Report.Error (
85                                                         451, loc, "The new () constraint " +
86                                                         "cannot be used with the `struct' " +
87                                                         "constraint.");
88                                                 return false;
89                                         }
90
91                                         if ((num_constraints > 0) || has_reference_type ||
92                                             has_value_type) {
93                                                 Report.Error (449, loc,
94                                                               "The `class' or `struct' " +
95                                                               "constraint must be first");
96                                                 return false;
97                                         }
98
99                                         if (sc == SpecialConstraint.ReferenceType)
100                                                 has_reference_type = true;
101                                         else
102                                                 has_value_type = true;
103                                         continue;
104                                 }
105
106                                 TypeExpr expr = ds.ResolveTypeExpr ((Expression) obj, false, loc);
107                                 if (expr == null)
108                                         return false;
109
110                                 if (expr is TypeParameterExpr) {
111                                         Report.Error (700, loc,
112                                                       "`{0}': naked type parameters cannot " +
113                                                       "be used as bounds", expr.Name);
114                                         return false;
115                                 }
116
117                                 if (expr.IsInterface)
118                                         iface_constraints.Add (expr);
119                                 else if (class_constraint != null) {
120                                         Report.Error (406, loc,
121                                                       "`{0}': the class constraint for `{1}' " +
122                                                       "must come before any other constraints.",
123                                                       expr.Name, name);
124                                         return false;
125                                 } else if (has_reference_type || has_value_type) {
126                                         Report.Error (450, loc, "`{0}': cannot specify both " +
127                                                       "a constraint class and the `class' " +
128                                                       "or `struct' constraint.", expr.Name);
129                                         return false;
130                                 } else
131                                         class_constraint = expr;
132
133                                 num_constraints++;
134                         }
135
136                         return true;
137                 }
138
139                 public TypeExpr[] InterfaceConstraints {
140                         get {
141                                 TypeExpr[] ifaces = new TypeExpr [iface_constraints.Count];
142                                 iface_constraints.CopyTo (ifaces, 0);
143                                 return ifaces;
144                         }
145                 }
146
147                 public bool ResolveTypes (EmitContext ec)
148                 {
149                         iface_constraint_types = new Type [iface_constraints.Count];
150
151                         for (int i = 0; i < iface_constraints.Count; i++) {
152                                 TypeExpr iface_constraint = (TypeExpr) iface_constraints [i];
153                                 Type resolved = iface_constraint.ResolveType (ec);
154                                 if (resolved == null)
155                                         return false;
156
157                                 for (int j = 0; j < i; j++) {
158                                         if (!iface_constraint_types [j].Equals (resolved))
159                                                 continue;
160
161                                         Report.Error (405, loc,
162                                                       "Duplicate constraint `{0}' for type " +
163                                                       "parameter `{1}'.", resolved, name);
164                                         return false;
165                                 }
166
167                                 iface_constraint_types [i] = resolved;
168                         }
169
170                         if (class_constraint != null) {
171                                 class_constraint_type = class_constraint.ResolveType (ec);
172                                 if (class_constraint_type == null)
173                                         return false;
174
175                                 if (class_constraint_type.IsSealed) {
176                                         Report.Error (701, loc,
177                                                       "`{0}' is not a valid bound.  Bounds " +
178                                                       "must be interfaces or non sealed " +
179                                                       "classes", class_constraint_type);
180                                         return false;
181                                 }
182
183                                 if ((class_constraint_type == TypeManager.array_type) ||
184                                     (class_constraint_type == TypeManager.delegate_type) ||
185                                     (class_constraint_type == TypeManager.enum_type) ||
186                                     (class_constraint_type == TypeManager.value_type) ||
187                                     (class_constraint_type == TypeManager.object_type)) {
188                                         Report.Error (702, loc,
189                                                       "Bound cannot be special class `{0}'",
190                                                       class_constraint_type);
191                                         return false;
192                                 }
193                         }
194
195                         if (has_reference_type)
196                                 class_constraint_type = TypeManager.object_type;
197                         else if (has_value_type)
198                                 class_constraint_type = TypeManager.value_type;
199
200                         return true;
201                 }
202
203                 public void Define (GenericTypeParameterBuilder type)
204                 {
205                         if (has_ctor_constraint)
206                                 type.Mono_SetConstructorConstraint ();
207                         if (has_reference_type)
208                                 type.Mono_SetReferenceTypeConstraint ();
209                         else if (has_value_type)
210                                 type.Mono_SetValueTypeConstraint ();
211                 }
212
213                 bool GenericConstraints.HasConstructor {
214                         get { return has_ctor_constraint; }
215                 }
216
217                 bool GenericConstraints.HasClassConstraint {
218                         get { return class_constraint_type != null; }
219                 }
220
221                 Type GenericConstraints.ClassConstraint {
222                         get { return class_constraint_type; }
223                 }
224
225                 Type[] GenericConstraints.InterfaceConstraints {
226                         get { return iface_constraint_types; }
227                 }
228         }
229
230         //
231         // This type represents a generic type parameter
232         //
233         public class TypeParameter : IMemberContainer {
234                 string name;
235                 Constraints constraints;
236                 Location loc;
237                 GenericTypeParameterBuilder type;
238
239                 public TypeParameter (string name, Constraints constraints, Location loc)
240                 {
241                         this.name = name;
242                         this.constraints = constraints;
243                         this.loc = loc;
244                 }
245
246                 public string Name {
247                         get {
248                                 return name;
249                         }
250                 }
251
252                 public Location Location {
253                         get {
254                                 return loc;
255                         }
256                 }
257
258                 public Constraints Constraints {
259                         get {
260                                 return constraints;
261                         }
262                 }
263
264                 public bool HasConstructorConstraint {
265                         get {
266                                 if (constraints != null)
267                                         return constraints.HasConstructorConstraint;
268
269                                 return false;
270                         }
271                 }
272
273                 public Type Type {
274                         get {
275                                 return type;
276                         }
277                 }
278
279                 public bool Resolve (DeclSpace ds)
280                 {
281                         if (constraints != null)
282                                 return constraints.Resolve (ds);
283
284                         return true;
285                 }
286
287                 public void Define (GenericTypeParameterBuilder type)
288                 {
289                         this.type = type;
290                         TypeExpr[] ifaces = null;
291                         if (constraints != null) {
292                                 ifaces = constraints.InterfaceConstraints;
293                                 constraints.Define (type);
294                         }
295                         TypeManager.AddTypeParameter (type, this, ifaces);
296                 }
297
298                 public bool DefineType (EmitContext ec)
299                 {
300                         if (constraints != null) {
301                                 if (!constraints.ResolveTypes (ec))
302                                         return false;
303
304                                 GenericConstraints gc = (GenericConstraints) constraints;
305
306                                 if (gc.HasClassConstraint)
307                                         type.SetBaseTypeConstraint (gc.ClassConstraint);
308
309                                 type.SetInterfaceConstraints (gc.InterfaceConstraints);
310                         }
311
312                         return true;
313                 }
314
315                 //
316                 // IMemberContainer
317                 //
318
319                 IMemberContainer IMemberContainer.Parent {
320                         get { return null; }
321                 }
322
323                 bool IMemberContainer.IsInterface {
324                         get { return true; }
325                 }
326
327                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
328                 {
329                         return FindMembers (mt, bf, null, null);
330                 }
331
332                 MemberCache IMemberContainer.MemberCache {
333                         get { return null; }
334                 }
335
336                 public MemberList FindMembers (MemberTypes mt, BindingFlags bf,
337                                                MemberFilter filter, object criteria)
338                 {
339                         if (constraints == null)
340                                 return MemberList.Empty;
341
342                         ArrayList members = new ArrayList ();
343
344                         GenericConstraints gc = (GenericConstraints) constraints;
345
346                         if (gc.HasClassConstraint) {
347                                 MemberList list = TypeManager.FindMembers (
348                                         gc.ClassConstraint, mt, bf, filter, criteria);
349
350                                 members.AddRange (list);
351                         }
352
353                         foreach (Type t in gc.InterfaceConstraints) {
354                                 MemberList list = TypeManager.FindMembers (
355                                         t, mt, bf, filter, criteria);
356
357                                 members.AddRange (list);
358                         }
359
360                         return new MemberList (members);
361                 }
362
363                 public override string ToString ()
364                 {
365                         return "TypeParameter[" + name + "]";
366                 }
367         }
368
369         //
370         // This type represents a generic type parameter reference.
371         //
372         // These expressions are born in a fully resolved state.
373         //
374         public class TypeParameterExpr : TypeExpr {
375                 TypeParameter type_parameter;
376
377                 public override string Name {
378                         get {
379                                 return type_parameter.Name;
380                         }
381                 }
382
383                 public TypeParameter TypeParameter {
384                         get {
385                                 return type_parameter;
386                         }
387                 }
388                 
389                 public TypeParameterExpr (TypeParameter type_parameter, Location loc)
390                 {
391                         this.type_parameter = type_parameter;
392                         this.loc = loc;
393                 }
394
395                 public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
396                 {
397                         type = type_parameter.Type;
398
399                         return this;
400                 }
401
402                 public void Error_CannotUseAsUnmanagedType (Location loc)
403                 {
404                         Report.Error (-203, loc, "Can not use type parameter as unamanged type");
405                 }
406         }
407
408         public class TypeArguments {
409                 public readonly Location Location;
410                 ArrayList args;
411                 Type[] atypes;
412                 bool has_type_args;
413                 bool created;
414                 
415                 public TypeArguments (Location loc)
416                 {
417                         args = new ArrayList ();
418                         this.Location = loc;
419                 }
420
421                 public void Add (Expression type)
422                 {
423                         if (created)
424                                 throw new InvalidOperationException ();
425
426                         args.Add (type);
427                 }
428
429                 public void Add (TypeArguments new_args)
430                 {
431                         if (created)
432                                 throw new InvalidOperationException ();
433
434                         args.AddRange (new_args.args);
435                 }
436
437                 public string[] GetDeclarations ()
438                 {
439                         string[] ret = new string [args.Count];
440                         for (int i = 0; i < args.Count; i++) {
441                                 SimpleName sn = args [i] as SimpleName;
442                                 if (sn != null) {
443                                         ret [i] = sn.Name;
444                                         continue;
445                                 }
446
447                                 Report.Error (81, Location, "Type parameter declaration " +
448                                               "must be an identifier not a type");
449                                 return null;
450                         }
451                         return ret;
452                 }
453
454                 public Type[] Arguments {
455                         get {
456                                 return atypes;
457                         }
458                 }
459
460                 public bool HasTypeArguments {
461                         get {
462                                 return has_type_args;
463                         }
464                 }
465
466                 public int Count {
467                         get {
468                                 return args.Count;
469                         }
470                 }
471
472                 public override string ToString ()
473                 {
474                         StringBuilder s = new StringBuilder ();
475
476                         int count = args.Count;
477                         for (int i = 0; i < count; i++){
478                                 //
479                                 // FIXME: Use TypeManager.CSharpname once we have the type
480                                 //
481                                 s.Append (args [i].ToString ());
482                                 if (i+1 < count)
483                                         s.Append (",");
484                         }
485                         return s.ToString ();
486                 }
487
488                 public bool Resolve (EmitContext ec)
489                 {
490                         DeclSpace ds = ec.DeclSpace;
491                         int count = args.Count;
492                         bool ok = true;
493
494                         atypes = new Type [count];
495                         
496                         for (int i = 0; i < count; i++){
497                                 TypeExpr te = ds.ResolveTypeExpr (
498                                         (Expression) args [i], false, Location);
499                                 if (te == null) {
500                                         ok = false;
501                                         continue;
502                                 }
503                                 if (te is TypeParameterExpr)
504                                         has_type_args = true;
505                                 atypes [i] = te.ResolveType (ec);
506
507                                 if (atypes [i] == null) {
508                                         Report.Error (246, Location, "Cannot find type `{0}'",
509                                                       te.Name);
510                                         ok = false;
511                                 }
512                         }
513                         return ok;
514                 }
515         }
516         
517         public class ConstructedType : TypeExpr {
518                 string name, full_name;
519                 TypeArguments args;
520                 Type[] gen_params, atypes;
521                 Type gt;
522                 
523                 public ConstructedType (string name, TypeArguments args, Location l)
524                 {
525                         loc = l;
526                         this.name = name + "!" + args.Count;
527                         this.args = args;
528
529                         eclass = ExprClass.Type;
530                         full_name = name + "<" + args.ToString () + ">";
531                 }
532
533                 public ConstructedType (string name, TypeParameter[] type_params, Location l)
534                         : this (type_params, l)
535                 {
536                         loc = l;
537
538                         this.name = name;
539                         full_name = name + "<" + args.ToString () + ">";
540                 }
541
542                 protected ConstructedType (TypeArguments args, Location l)
543                 {
544                         loc = l;
545                         this.args = args;
546
547                         eclass = ExprClass.Type;
548                 }
549
550                 protected ConstructedType (TypeParameter[] type_params, Location l)
551                 {
552                         loc = l;
553
554                         args = new TypeArguments (l);
555                         foreach (TypeParameter type_param in type_params)
556                                 args.Add (new TypeParameterExpr (type_param, l));
557
558                         eclass = ExprClass.Type;
559                 }
560
561                 public ConstructedType (Type t, TypeParameter[] type_params, Location l)
562                         : this (type_params, l)
563                 {
564                         gt = t.GetGenericTypeDefinition ();
565
566                         this.name = gt.FullName;
567                         full_name = gt.FullName + "<" + args.ToString () + ">";
568                 }
569
570                 public ConstructedType (Type t, TypeArguments args, Location l)
571                         : this (args, l)
572                 {
573                         gt = t.GetGenericTypeDefinition ();
574
575                         this.name = gt.FullName;
576                         full_name = gt.FullName + "<" + args.ToString () + ">";
577                 }
578
579                 public TypeArguments TypeArguments {
580                         get { return args; }
581                 }
582
583                 protected string DeclarationName {
584                         get {
585                                 StringBuilder sb = new StringBuilder ();
586                                 sb.Append (gt.FullName);
587                                 sb.Append ("<");
588                                 for (int i = 0; i < gen_params.Length; i++) {
589                                         if (i > 0)
590                                                 sb.Append (",");
591                                         sb.Append (gen_params [i]);
592                                 }
593                                 sb.Append (">");
594                                 return sb.ToString ();
595                         }
596                 }
597
598                 protected bool CheckConstraints (EmitContext ec, int index)
599                 {
600                         Type atype = atypes [index];
601                         Type ptype = gen_params [index];
602
603                         if (atype == ptype)
604                                 return true;
605
606                         Expression aexpr = new EmptyExpression (atype);
607
608                         //
609                         // First, check the class constraint.
610                         //
611
612                         Type parent = ptype.BaseType;
613                         if ((parent != null) && (parent != TypeManager.object_type)) {
614                                 if (!Convert.ImplicitStandardConversionExists (aexpr, parent)) {
615                                         Report.Error (309, loc, "The type `{0}' must be " +
616                                                       "convertible to `{1}' in order to " +
617                                                       "use it as parameter `{2}' in the " +
618                                                       "generic type or method `{3}'",
619                                                       atype, parent, ptype, DeclarationName);
620                                         return false;
621                                 }
622                         }
623
624                         //
625                         // Now, check the interface constraints.
626                         //
627                         foreach (Type itype in ptype.GetInterfaces ()) {
628                                 if (!Convert.ImplicitStandardConversionExists (aexpr, itype)) {
629                                         Report.Error (309, loc, "The type `{0}' must be " +
630                                                       "convertible to `{1}' in order to " +
631                                                       "use it as parameter `{2}' in the " +
632                                                       "generic type or method `{3}'",
633                                                       atype, itype, ptype, DeclarationName);
634                                         return false;
635                                 }
636                         }
637
638                         //
639                         // Finally, check the constructor constraint.
640                         //
641
642                         if (!TypeManager.HasConstructorConstraint (ptype))
643                                 return true;
644
645                         MethodGroupExpr mg = Expression.MemberLookup (
646                                 ec, atype, ".ctor", MemberTypes.Constructor,
647                                 BindingFlags.Public | BindingFlags.Instance |
648                                 BindingFlags.DeclaredOnly, loc)
649                                 as MethodGroupExpr;
650
651                         if (atype.IsAbstract || (mg == null) || !mg.IsInstance) {
652                                 Report.Error (310, loc, "The type `{0}' must have a public " +
653                                               "parameterless constructor in order to use it " +
654                                               "as parameter `{1}' in the generic type or " +
655                                               "method `{2}'", atype, ptype, DeclarationName);
656                                 return false;
657                         }
658
659                         return true;
660                 }
661
662                 public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
663                 {
664                         if (gt != null)
665                                 return this;
666
667                         //
668                         // First, resolve the generic type.
669                         //
670                         DeclSpace ds;
671                         Type nested = ec.DeclSpace.FindNestedType (loc, name, out ds);
672                         if (nested != null) {
673                                 gt = nested.GetGenericTypeDefinition ();
674
675                                 TypeArguments new_args = new TypeArguments (loc);
676                                 foreach (TypeParameter param in ds.TypeParameters)
677                                         new_args.Add (new TypeParameterExpr (param, loc));
678                                 new_args.Add (args);
679
680                                 args = new_args;
681                                 return this;
682                         }
683
684                         Type t;
685                         int num_args;
686
687                         SimpleName sn = new SimpleName (name, loc);
688                         TypeExpr resolved = sn.ResolveAsTypeTerminal (ec);
689                         if ((resolved == null) || (resolved.Type == null)) {
690                                 Report.Error (246, loc,
691                                               "The type or namespace name `{0}<...>' "+
692                                               "could not be found", Basename);
693                                 return null;
694                         }
695
696                         t = resolved.Type;
697                         if (t == null) {
698                                 Report.Error (246, loc, "Cannot find type `{0}'<...>",
699                                               Basename);
700                                 return null;
701                         }
702
703                         num_args = TypeManager.GetNumberOfTypeArguments (t);
704                         if (num_args == 0) {
705                                 Report.Error (308, loc,
706                                               "The non-generic type `{0}' cannot " +
707                                               "be used with type arguments.",
708                                               TypeManager.CSharpName (t));
709                                 return null;
710                         }
711
712                         gt = t.GetGenericTypeDefinition ();
713                         return this;
714                 }
715
716                 public override Type ResolveType (EmitContext ec)
717                 {
718                         if (type != null)
719                                 return type;
720                         if (DoResolveAsTypeStep (ec) == null)
721                                 return null;
722
723                         //
724                         // Resolve the arguments.
725                         //
726                         if (args.Resolve (ec) == false)
727                                 return null;
728
729                         gen_params = gt.GetGenericArguments ();
730                         atypes = args.Arguments;
731
732                         if (atypes.Length != gen_params.Length) {
733                                 Report.Error (305, loc,
734                                               "Using the generic type `{0}' " +
735                                               "requires {1} type arguments",
736                                               TypeManager.GetFullName (gt),
737                                               gen_params.Length);
738                                 return null;
739                         }
740
741                         for (int i = 0; i < gen_params.Length; i++) {
742                                 if (!CheckConstraints (ec, i))
743                                         return null;
744                         }
745
746                         //
747                         // Now bind the parameters.
748                         //
749                         type = gt.BindGenericParameters (atypes);
750                         return type;
751                 }
752
753                 public Expression GetMemberAccess (EmitContext ec)
754                 {
755                         TypeExpr current;
756                         if (ec.TypeContainer.CurrentType != null)
757                                 current = ec.TypeContainer.CurrentType;
758                         else
759                                 current = new TypeExpression (ec.ContainerType, loc);
760
761                         return new MemberAccess (current, Basename, args, loc);
762                 }
763
764                 public override bool CheckAccessLevel (DeclSpace ds)
765                 {
766                         return ds.CheckAccessLevel (gt);
767                 }
768
769                 public override bool AsAccessible (DeclSpace ds, int flags)
770                 {
771                         return ds.AsAccessible (gt, flags);
772                 }
773
774                 public override bool IsClass {
775                         get { return gt.IsClass; }
776                 }
777
778                 public override bool IsValueType {
779                         get { return gt.IsValueType; }
780                 }
781
782                 public override bool IsInterface {
783                         get { return gt.IsInterface; }
784                 }
785
786                 public override bool IsSealed {
787                         get { return gt.IsSealed; }
788                 }
789
790                 public override bool IsAttribute {
791                         get { return false; }
792                 }
793
794                 public override TypeExpr[] GetInterfaces ()
795                 {
796                         TypeExpr[] ifaces = TypeManager.GetInterfaces (gt);
797                         return ifaces;
798                 }
799
800                 public override bool Equals (object obj)
801                 {
802                         ConstructedType cobj = obj as ConstructedType;
803                         if (cobj == null)
804                                 return false;
805
806                         if ((type == null) || (cobj.type == null))
807                                 return false;
808
809                         return type == cobj.type;
810                 }
811
812                 public string Basename {
813                         get {
814                                 int pos = name.LastIndexOf ('!');
815                                 if (pos >= 0)
816                                         return name.Substring (0, pos);
817                                 else
818                                         return name;
819                         }
820                 }
821
822                 public override string Name {
823                         get {
824                                 return full_name;
825                         }
826                 }
827         }
828
829         public class GenericMethod : DeclSpace
830         {
831                 public GenericMethod (NamespaceEntry ns, TypeContainer parent,
832                                       MemberName name, Attributes attrs, Location l)
833                         : base (ns, parent, name, attrs, l)
834                 { }
835
836                 public override TypeBuilder DefineType ()
837                 {
838                         throw new Exception ();
839                 }
840
841                 public override bool Define (TypeContainer parent)
842                 {
843                         for (int i = 0; i < TypeParameters.Length; i++)
844                                 if (!TypeParameters [i].Resolve (parent))
845                                         return false;
846
847                         return true;
848                 }
849
850                 public bool Define (TypeContainer parent, MethodBuilder mb)
851                 {
852                         if (!Define (parent))
853                                 return false;
854
855                         GenericTypeParameterBuilder[] gen_params;
856                         gen_params = mb.DefineGenericParameters (MemberName.TypeParameters);
857                         for (int i = 0; i < TypeParameters.Length; i++)
858                                 TypeParameters [i].Define (gen_params [i]);
859
860                         return true;
861                 }
862
863                 public bool DefineType (EmitContext ec, MethodBuilder mb)
864                 {
865                         for (int i = 0; i < TypeParameters.Length; i++)
866                                 if (!TypeParameters [i].DefineType (ec))
867                                         return false;
868
869                         return true;
870                 }
871
872                 public override bool DefineMembers (TypeContainer parent)
873                 {
874                         return true;
875                 }
876
877                 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
878                                                         MemberFilter filter, object criteria)
879                 {
880                         throw new Exception ();
881                 }               
882
883                 public override MemberCache MemberCache {
884                         get {
885                                 throw new Exception ();
886                         }
887                 }
888         }
889
890         public class DefaultValueExpression : Expression
891         {
892                 Expression expr;
893                 LocalTemporary temp_storage;
894
895                 public DefaultValueExpression (Expression expr, Location loc)
896                 {
897                         this.expr = expr;
898                         this.loc = loc;
899                 }
900
901                 public override Expression DoResolve (EmitContext ec)
902                 {
903                         type = ec.DeclSpace.ResolveType (expr, false, loc);
904                         if (type == null)
905                                 return null;
906
907                         if (type.IsGenericParameter || TypeManager.IsValueType (type))
908                                 temp_storage = new LocalTemporary (ec, type);
909
910                         eclass = ExprClass.Variable;
911                         return this;
912                 }
913
914                 public override void Emit (EmitContext ec)
915                 {
916                         if (temp_storage != null) {
917                                 temp_storage.AddressOf (ec, AddressOp.LoadStore);
918                                 ec.ig.Emit (OpCodes.Initobj, type);
919                                 temp_storage.Emit (ec);
920                         } else
921                                 ec.ig.Emit (OpCodes.Ldnull);
922                 }
923         }
924 }