**** Merged from MCS ****
[mono-project.git] / mcs / ilasm / codegen / ExternMethodRef.cs
blob87333b0be6fc83c0b7ab1f47476bccd12f4ffcc1
1 //
2 // Mono.ILASM.ExternMethodRef
3 //
4 // Author(s):
5 // Jackson Harper (Jackson@LatitudeGeo.com)
6 //
7 // (C) 2003 Jackson Harper, All rights reserved
8 //
11 using System;
12 using System.Collections;
14 namespace Mono.ILASM {
16 public class ExternMethodRef : IMethodRef {
18 private ExternTypeRef owner;
19 private ITypeRef ret_type;
20 private string name;
21 private ITypeRef[] param;
22 private PEAPI.CallConv call_conv;
24 private PEAPI.Method peapi_method;
25 private bool is_resolved;
27 public ExternMethodRef (ExternTypeRef owner, ITypeRef ret_type,
28 PEAPI.CallConv call_conv, string name, ITypeRef[] param)
30 this.owner = owner;
31 this.ret_type = ret_type;
32 this.name = name;
33 this.param = param;
34 this.call_conv = call_conv;
36 is_resolved = false;
39 public PEAPI.Method PeapiMethod {
40 get { return peapi_method; }
43 public PEAPI.CallConv CallConv {
44 get { return call_conv; }
45 set { call_conv = value; }
48 public void Resolve (CodeGen code_gen)
50 if (is_resolved)
51 return;
53 if ((call_conv & PEAPI.CallConv.Vararg) != 0) {
54 ResolveVararg (code_gen);
55 return;
58 PEAPI.Type[] param_list = new PEAPI.Type[param.Length];
59 string write_name;
61 ret_type.Resolve (code_gen);
63 int count = 0;
64 foreach (ITypeRef typeref in param) {
65 typeref.Resolve (code_gen);
66 param_list[count++] = typeref.PeapiType;
69 if (name == "<init>")
70 write_name = ".ctor";
71 else
72 write_name = name;
74 owner.Resolve (code_gen);
76 if (owner.UseTypeSpec) {
77 PEAPI.Type owner_ref = owner.PeapiType;
78 peapi_method = code_gen.PEFile.AddMethodToTypeSpec (owner_ref, write_name,
79 ret_type.PeapiType, param_list);
80 } else {
81 PEAPI.ClassRef owner_ref;
82 owner_ref = (PEAPI.ClassRef) owner.PeapiType;
83 peapi_method = owner_ref.AddMethod (write_name,
84 ret_type.PeapiType, param_list);
87 peapi_method.AddCallConv (call_conv);
89 is_resolved = true;
92 protected void ResolveVararg (CodeGen code_gen)
94 if (is_resolved)
95 return;
97 ArrayList param_list = new ArrayList ();
98 ArrayList opt_list = new ArrayList ();
99 bool in_opt = false;
100 string write_name;
102 ret_type.Resolve (code_gen);
104 int count = 0;
105 foreach (ITypeRef typeref in param) {
106 if (in_opt) {
107 typeref.Resolve (code_gen);
108 opt_list.Add (typeref.PeapiType);
109 } else if (TypeRef.Ellipsis == typeref) {
110 in_opt = true;
111 } else {
112 typeref.Resolve (code_gen);
113 param_list.Add (typeref.PeapiType);
117 if (name == "<init>")
118 write_name = ".ctor";
119 else
120 write_name = name;
122 if (owner.IsArray)
123 throw new NotImplementedException ("Vararg methods on arrays are not supported yet.");
125 owner.Resolve (code_gen);
127 if (owner.UseTypeSpec) {
128 PEAPI.Type owner_ref = owner.PeapiType;
129 peapi_method = code_gen.PEFile.AddVarArgMethodToTypeSpec (owner_ref,
130 write_name, ret_type.PeapiType,
131 (PEAPI.Type[]) param_list.ToArray (typeof (PEAPI.Type)),
132 (PEAPI.Type[]) opt_list.ToArray (typeof (PEAPI.Type)));
133 } else {
134 PEAPI.ClassRef owner_ref;
135 owner_ref = (PEAPI.ClassRef) owner.PeapiType;
136 peapi_method = owner_ref.AddVarArgMethod (write_name,
137 ret_type.PeapiType,
138 (PEAPI.Type[]) param_list.ToArray (typeof (PEAPI.Type)),
139 (PEAPI.Type[]) opt_list.ToArray (typeof (PEAPI.Type)));
143 peapi_method.AddCallConv (call_conv);
145 is_resolved = true;