dlr bug
[mcs.git] / ilasm / codegen / PeapiTypeRef.cs
blob704ba2df08699924cbae80fbe0e3d0a1a93ed0fd
1 //
2 // Mono.ILASM.PeapiTypeRef
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 {
15 public class Pair {
16 private PEAPI.Type type;
17 private string sig;
19 public Pair (PEAPI.Type type, string sig)
21 this.type = type;
22 this.sig = sig;
25 public override int GetHashCode ()
27 return type.GetHashCode () ^ sig.GetHashCode ();
30 public override bool Equals (Object o)
32 Pair p = o as Pair;
34 if (p == null)
35 return false;
37 return (p.type == this.type && p.sig == this.sig);
41 public class PeapiTypeRef {
43 private PEAPI.Type peapi_type;
44 private bool is_pinned;
45 private bool is_array;
46 private bool is_ref;
47 private bool use_type_spec;
49 private static Hashtable type_table = new Hashtable ();
51 public PeapiTypeRef (PEAPI.Type peapi_type)
53 this.peapi_type = peapi_type;
54 is_pinned = false;
55 is_array = false;
56 is_ref = false;
57 use_type_spec = false;
60 public bool IsPinned {
61 get { return is_pinned; }
64 public bool IsArray {
65 get { return is_array; }
68 public bool IsRef {
69 get { return is_ref; }
72 public bool UseTypeSpec {
73 get { return use_type_spec; }
76 public PEAPI.Type PeapiType {
77 get { return peapi_type; }
80 public void MakeArray ()
82 PEAPI.Type type;
84 use_type_spec = true;
85 is_array = true;
87 Pair p = new Pair (peapi_type, "[]");
88 type = type_table [p] as PEAPI.Type;
89 if (type == null) {
90 type = new PEAPI.ZeroBasedArray (peapi_type);
91 type_table [p] = type;
93 peapi_type = type;
96 public void MakeBoundArray (ArrayList bound_list)
98 use_type_spec = true;
99 is_array = true;
101 int dimen = bound_list.Count;
102 int[] lower_array = new int[dimen];
103 int[] size_array = new int[dimen];
104 int [] lobounds = null;
105 int [] sizes = null;
106 int num_lower, num_sizes;
107 string sigmod = "";
108 PEAPI.Type type;
109 Pair p;
111 sigmod += "[";
112 for (int i=0; i<bound_list.Count; i++) {
113 DictionaryEntry e = (DictionaryEntry) bound_list [i];
114 if (e.Key != TypeRef.Ellipsis)
115 sigmod += e.Key;
116 sigmod += "...";
117 if (e.Value != TypeRef.Ellipsis)
118 sigmod += e.Value;
119 if (i + 1 < bound_list.Count)
120 sigmod += ", ";
122 sigmod += "]";
124 p = new Pair (peapi_type, sigmod);
125 type = type_table [p] as PEAPI.Type;
126 if (type != null) {
127 peapi_type = type;
128 return;
131 num_sizes = num_lower = 0;
132 // TODO: There should probably be an error reported if
133 // something like [3...,3...5] is done
134 for (int i=0; i<dimen; i++) {
135 if (bound_list [i] == null)
136 continue;
138 DictionaryEntry bound = (DictionaryEntry) bound_list [i];
140 if (bound.Key != TypeRef.Ellipsis) {
141 /* Lower bound specified */
142 lower_array [i] = (int) bound.Key;
143 num_lower = i + 1;
145 if (bound.Value != TypeRef.Ellipsis) {
146 size_array [i] = (int) bound.Value;
147 if (bound.Key != TypeRef.Ellipsis)
148 /* .Value is Upper bound eg [1...5] */
149 size_array [i] -= lower_array [i] - 1;
150 num_sizes = i + 1;
154 if (num_lower > 0) {
155 lobounds = new int [num_lower];
156 Array.Copy (lower_array, lobounds, num_lower);
159 if (num_sizes > 0) {
160 sizes = new int [num_sizes];
161 Array.Copy (size_array, sizes, num_sizes);
164 peapi_type = new PEAPI.BoundArray (peapi_type,
165 (uint) dimen, lobounds, sizes);
166 type_table [p] = peapi_type;
169 public void MakeManagedPointer ()
171 PEAPI.Type type;
172 use_type_spec = true;
173 is_ref = true;
175 Pair p = new Pair (peapi_type, "&");
176 type = type_table [p] as PEAPI.Type;
177 if (type == null) {
178 type = new PEAPI.ManagedPointer (peapi_type);
179 type_table [p] = type;
181 peapi_type = type;
184 public void MakeUnmanagedPointer ()
186 PEAPI.Type type;
187 use_type_spec = true;
189 Pair p = new Pair (peapi_type, "*");
190 type = type_table [p] as PEAPI.Type;
191 if (type == null) {
192 type = new PEAPI.UnmanagedPointer (peapi_type);
193 type_table [p] = type;
195 peapi_type = type;
198 public void MakeCustomModified (CodeGen code_gen, PEAPI.CustomModifier modifier,
199 BaseClassRef klass)
201 PEAPI.Type type;
203 use_type_spec = true;
205 Pair p = new Pair (peapi_type, modifier.ToString ());
206 type = type_table [p] as PEAPI.Type;
207 if (type == null) {
208 klass.Resolve (code_gen);
209 type = new PEAPI.CustomModifiedType (peapi_type,
210 modifier, klass.PeapiClass);
211 type_table [p] = type;
213 peapi_type = type;
216 public void MakePinned ()
218 use_type_spec = true;
219 is_pinned = true;
222 public void Resolve (CodeGen code_gen)