2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / ilasm / codegen / MethodPointerTypeRef.cs
blobca33f854a19e10404ef3414bb29681f75900a2ef
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 //
11 using System;
12 using System.Text;
13 using System.Collections;
15 namespace Mono.ILASM {
17 public class MethodPointerTypeRef : BaseTypeRef {
19 private PEAPI.CallConv callconv;
20 private BaseTypeRef ret;
21 private ArrayList param_list;
23 public MethodPointerTypeRef (PEAPI.CallConv callconv, BaseTypeRef ret, ArrayList param_list)
24 : this (callconv, ret, param_list, null, String.Empty)
28 public MethodPointerTypeRef (PEAPI.CallConv callconv, BaseTypeRef ret, ArrayList param_list, ArrayList conv_list, string sig_mod)
29 : base (String.Empty, conv_list, sig_mod)
31 this.callconv = callconv;
32 this.ret = ret;
33 this.param_list = param_list;
35 // We just need these to not break the interface
36 full_name = BuildTypeName ();
37 //sig_mod = String.Empty;
40 private String BuildTypeName ()
42 StringBuilder builder = new StringBuilder ();
43 builder.Append ("method ");
44 if (callconv != PEAPI.CallConv.Default) {
45 builder.Append (callconv.ToString ());
46 builder.Append (' ');
48 builder.Append (ret.FullName);
49 builder.Append ("*(");
50 if (param_list != null) {
51 bool first = true;
52 foreach (ParamDef paramdef in param_list) {
53 if (!first)
54 builder.Append (',');
55 builder.Append (paramdef.TypeName);
56 first = false;
59 builder.Append (')');
60 return builder.ToString ();
63 public override BaseTypeRef Clone ()
65 return new MethodPointerTypeRef (callconv, ret,
66 param_list == null ? null : (ArrayList) param_list.Clone (),
67 (ArrayList) ConversionList.Clone (), sig_mod);
70 public override void Resolve (CodeGen code_gen)
72 if (is_resolved)
73 return;
75 PEAPI.Type [] arg_array;
76 PEAPI.Type [] opt_array;
77 bool is_vararg = false;
79 if (param_list != null) {
80 ArrayList opt_list = new ArrayList ();
81 ArrayList arg_list = new ArrayList ();
82 bool in_opt = false;
83 int max = param_list.Count;
85 for (int i = 0; i < max; i++) {
86 ParamDef param = (ParamDef) param_list [i];
88 if (param.IsSentinel ()) {
89 is_vararg = true;
90 in_opt = true;
91 param.Type.Resolve (code_gen);
92 } else if (in_opt) {
93 param.Type.Resolve (code_gen);
94 opt_list.Add (param.Type.PeapiType);
95 } else {
96 param.Type.Resolve (code_gen);
97 arg_list.Add (param.Type.PeapiType);
101 arg_array = (PEAPI.Type []) arg_list.ToArray (typeof (PEAPI.Type));
102 opt_array = (PEAPI.Type []) opt_list.ToArray (typeof (PEAPI.Type));
103 } else {
104 arg_array = new PEAPI.Type [0];
105 opt_array = new PEAPI.Type [0];
108 ret.Resolve (code_gen);
110 type = new PEAPI.MethPtrType (callconv, ret.PeapiType, arg_array, is_vararg, opt_array);
111 type = Modify (code_gen, type);
113 is_resolved = true;
116 protected override BaseMethodRef CreateMethodRef (BaseTypeRef ret_type, PEAPI.CallConv call_conv,
117 string name, BaseTypeRef[] param, int gen_param_count)
119 return new TypeSpecMethodRef (this, call_conv, ret_type, name, param, gen_param_count);
122 protected override IFieldRef CreateFieldRef (BaseTypeRef ret_type, string name)
124 return new TypeSpecFieldRef (this, ret_type, name);