In ilasm/tests:
[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 : ModifiableType, ITypeRef {
17
18                 private PEAPI.CallConv callconv;
19                 private ITypeRef ret;
20                 private ArrayList param_list;
21                 private PEAPI.Type type;
22                 private string full_name;
23                 private string sig_mod;
24                 private bool is_resolved;
25
26                 public MethodPointerTypeRef (PEAPI.CallConv callconv, ITypeRef ret, ArrayList param_list)
27                 {
28                         this.callconv = callconv;
29                         this.ret = ret;
30                         this.param_list = param_list;
31
32                         // We just need these to not break the interface
33                         full_name = String.Empty;
34                         sig_mod = String.Empty;
35                 }
36
37                 public string FullName {
38                         get { return full_name + sig_mod; }
39                 }
40
41                 public override string SigMod {
42                         get { return sig_mod; }
43                         set { sig_mod = value; }
44                 }
45
46                 public PEAPI.Type PeapiType {
47                         get {
48                                 return type;
49                         }
50                 }
51                 
52                 public void Resolve (CodeGen code_gen)
53                 {
54                         if (is_resolved)
55                                 return;
56
57                         PEAPI.Type [] arg_array;
58                         PEAPI.Type [] opt_array;
59                         bool is_vararg = false;
60
61                         if (param_list != null) {
62                                 ArrayList opt_list = new ArrayList ();
63                                 ArrayList arg_list = new ArrayList ();
64                                 ParamDef last = null;
65                                 bool in_opt = false;
66                                 int max = param_list.Count;
67
68                                 for (int i = 0; i < max; i++) {
69                                         ParamDef param = (ParamDef) param_list [i];
70
71                                         if (param.IsSentinel ()) {
72                                                 is_vararg = true;
73                                                 in_opt = true;
74                                                 param.Type.Resolve (code_gen);
75                                         } else if (in_opt) {
76                                                 param.Type.Resolve (code_gen);
77                                                 opt_list.Add (param.Type.PeapiType);
78                                         } else {
79                                                 param.Type.Resolve (code_gen);
80                                                 arg_list.Add (param.Type.PeapiType);
81                                         }
82                                 }
83
84                                 arg_array = (PEAPI.Type []) arg_list.ToArray (typeof (PEAPI.Type));
85                                 opt_array = (PEAPI.Type []) opt_list.ToArray (typeof (PEAPI.Type));
86                         } else {
87                                 arg_array = new PEAPI.Type [0];
88                                 opt_array = new PEAPI.Type [0];
89                         }
90
91                         ret.Resolve (code_gen);
92
93                         type = new PEAPI.MethPtrType (callconv, ret.PeapiType, arg_array, is_vararg, opt_array);
94                         type = Modify (code_gen, type);
95
96                         is_resolved = true;
97                 }
98
99                 public IMethodRef GetMethodRef (ITypeRef ret_type, PEAPI.CallConv call_conv,
100                                 string name, ITypeRef[] param, int gen_param_count)
101                 {
102                         return new TypeSpecMethodRef (this, ret_type, call_conv, name, param, gen_param_count);
103                 }
104
105                 public IFieldRef GetFieldRef (ITypeRef ret_type, string name)
106                 {
107                         return new TypeSpecFieldRef (this, ret_type, name);
108                 }
109
110         }
111
112 }
113