[corlib] Assume UTC if no $TZ set. Fixes #30360
[mono.git] / mcs / ilasm / codegen / PeapiTypeRef.cs
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 //
9
10
11 using System;
12 using System.Collections;
13
14 namespace Mono.ILASM {
15         public class Pair {
16                 private PEAPI.Type type;
17                 private string sig;
18
19                 public Pair (PEAPI.Type type, string sig)
20                 {
21                         this.type = type;
22                         this.sig = sig;
23                 }
24
25                 public override int GetHashCode ()
26                 {
27                         return type.GetHashCode () ^ sig.GetHashCode (); 
28                 }
29
30                 public override bool Equals (Object o)
31                 {
32                         Pair p = o as Pair;
33
34                         if (p == null)
35                                 return false;
36                         
37                         return (p.type == this.type && p.sig == this.sig);
38                 }
39         }
40
41         public class PeapiTypeRef  {
42
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;
48
49                 private static Hashtable type_table = new Hashtable ();
50
51                 public PeapiTypeRef (PEAPI.Type peapi_type)
52                 {
53                         this.peapi_type = peapi_type;
54                         is_pinned = false;
55                         is_array = false;
56                         is_ref = false;
57                         use_type_spec = false;
58                 }
59
60                 public bool IsPinned {
61                         get { return is_pinned; }
62                 }
63
64                 public bool IsArray {
65                         get { return is_array; }
66                 }
67
68                 public bool IsRef {
69                         get { return is_ref; }
70                 }
71
72                 public bool UseTypeSpec {
73                         get { return use_type_spec; }
74                 }
75
76                 public PEAPI.Type PeapiType {
77                         get { return peapi_type; }
78                 }
79
80                 public void MakeArray ()
81                 {
82                         PEAPI.Type type;
83
84                         use_type_spec = true;
85                         is_array = true;
86
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;
92                         }
93                         peapi_type = type;
94                 }
95
96                 public void MakeBoundArray (ArrayList bound_list)
97                 {
98                         use_type_spec = true;
99                         is_array = true;
100
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;
110
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 += ", ";
121                         }
122                         sigmod += "]";
123
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;
129                         }
130
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;
137                                         
138                                 DictionaryEntry bound = (DictionaryEntry) bound_list [i];
139                                 
140                                 if (bound.Key != TypeRef.Ellipsis) {
141                                         /* Lower bound specified */
142                                         lower_array [i] = (int) bound.Key;
143                                         num_lower = i + 1;
144                                 }
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;
151                                 }
152                         }
153
154                         if (num_lower > 0) {
155                                 lobounds = new int [num_lower];
156                                 Array.Copy (lower_array, lobounds, num_lower);
157                         }
158
159                         if (num_sizes > 0) {
160                                 sizes = new int [num_sizes];
161                                 Array.Copy (size_array, sizes, num_sizes);
162                         }
163
164                         peapi_type = new PEAPI.BoundArray (peapi_type,
165                                                 (uint) dimen, lobounds, sizes);
166                         type_table [p] = peapi_type;
167                 }
168
169                 public void MakeManagedPointer ()
170                 {
171                         PEAPI.Type type;
172                         use_type_spec = true;
173                         is_ref = true;
174
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;
180                         }
181                         peapi_type = type;
182                 }
183
184                 public void MakeUnmanagedPointer ()
185                 {
186                         PEAPI.Type type;
187                         use_type_spec = true;
188
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;
194                         }
195                         peapi_type = type;
196                 }
197
198                 public void MakeCustomModified (CodeGen code_gen, PEAPI.CustomModifier modifier,
199                                 BaseTypeRef klass)
200                 {
201                         PEAPI.Type type;
202
203                         use_type_spec = true;
204                         
205                         Pair p = new Pair (peapi_type, modifier.ToString ());
206                         type = type_table [p] as PEAPI.Type;
207                         if (type == null) {
208                                 type = GetType (code_gen, modifier, klass);
209                                 type_table [p] = type;
210                         }
211                         peapi_type = type;
212                 }
213
214                 PEAPI.Type GetType (CodeGen code_gen, PEAPI.CustomModifier modifier, BaseTypeRef klass)
215                 {
216                         klass.Resolve (code_gen);
217                         var bcr = klass as BaseClassRef;
218                         if (bcr != null)
219                                 return new PEAPI.CustomModifiedType (peapi_type, modifier, bcr.PeapiClass);
220
221                         var pt = klass as PrimitiveTypeRef;
222                                 return new PEAPI.CustomModifiedType (peapi_type, modifier, code_gen.PEFile.AddPrimitiveType ((PEAPI.PrimitiveType) pt.PeapiType));
223
224                         throw new NotSupportedException (klass.GetType ().ToString ());
225                 }
226
227                 public void MakePinned ()
228                 {
229                         use_type_spec = true;
230                         is_pinned = true;
231                 }
232
233                 public void Resolve (CodeGen code_gen)
234                 {
235
236                 }
237
238
239         }
240
241 }
242