Add support for custom attributes on generic type parameters.
[mono.git] / mcs / ilasm / codegen / MethodPointerTypeRef.cs
1 //
2 // Mono.ILASM.MethodPointerTypeRef
3 //
4 // Author(s):
5 //  Jackson Harper (jackson@ximian.com)
6 //
7 // Copyright 2004 Novell, Inc (http://www.novell.com)
8 //
9
10
11 using System;
12 using System.Collections;
13
14 namespace Mono.ILASM {
15
16         public class MethodPointerTypeRef : BaseTypeRef {
17
18                 private PEAPI.CallConv callconv;
19                 private BaseTypeRef ret;
20                 private ArrayList param_list;
21
22                 public MethodPointerTypeRef (PEAPI.CallConv callconv, BaseTypeRef ret, ArrayList param_list)
23                         : base (String.Empty)
24                 {
25                         this.callconv = callconv;
26                         this.ret = ret;
27                         this.param_list = param_list;
28
29                         // We just need these to not break the interface
30                         //full_name = String.Empty;
31                         sig_mod = String.Empty;
32                 }
33
34                 public override void Resolve (CodeGen code_gen)
35                 {
36                         if (is_resolved)
37                                 return;
38
39                         PEAPI.Type [] arg_array;
40                         PEAPI.Type [] opt_array;
41                         bool is_vararg = false;
42
43                         if (param_list != null) {
44                                 ArrayList opt_list = new ArrayList ();
45                                 ArrayList arg_list = new ArrayList ();
46                                 ParamDef last = null;
47                                 bool in_opt = false;
48                                 int max = param_list.Count;
49
50                                 for (int i = 0; i < max; i++) {
51                                         ParamDef param = (ParamDef) param_list [i];
52
53                                         if (param.IsSentinel ()) {
54                                                 is_vararg = true;
55                                                 in_opt = true;
56                                                 param.Type.Resolve (code_gen);
57                                         } else if (in_opt) {
58                                                 param.Type.Resolve (code_gen);
59                                                 opt_list.Add (param.Type.PeapiType);
60                                         } else {
61                                                 param.Type.Resolve (code_gen);
62                                                 arg_list.Add (param.Type.PeapiType);
63                                         }
64                                 }
65
66                                 arg_array = (PEAPI.Type []) arg_list.ToArray (typeof (PEAPI.Type));
67                                 opt_array = (PEAPI.Type []) opt_list.ToArray (typeof (PEAPI.Type));
68                         } else {
69                                 arg_array = new PEAPI.Type [0];
70                                 opt_array = new PEAPI.Type [0];
71                         }
72
73                         ret.Resolve (code_gen);
74
75                         type = new PEAPI.MethPtrType (callconv, ret.PeapiType, arg_array, is_vararg, opt_array);
76                         type = Modify (code_gen, type);
77
78                         is_resolved = true;
79                 }
80
81                 protected override BaseMethodRef CreateMethodRef (BaseTypeRef ret_type, PEAPI.CallConv call_conv,
82                                 string name, BaseTypeRef[] param, int gen_param_count)
83                 {
84                         return new TypeSpecMethodRef (this, call_conv, ret_type, name, param, gen_param_count);
85                 }
86
87                 protected override IFieldRef CreateFieldRef (BaseTypeRef ret_type, string name)
88                 {
89                         return new TypeSpecFieldRef (this, ret_type, name);
90                 }
91
92         }
93
94 }
95