* ITypeRef.cs, PeapiTypeRef.cs, TypeRef.cs: Quick hack for custom
[mono.git] / mcs / ilasm / codegen / TypeRef.cs
1 //
2 // Mono.ILASM.TypeRef
3 //
4 // Author(s):
5 //  Jackson Harper (Jackson@LatitudeGeo.com)
6 //
7 // (C) 2003 Jackson Harper, All rights reserved
8 //
9
10 using System;
11 using System.Collections;
12
13 namespace Mono.ILASM {
14
15         /// <summary>
16         /// Reference to a type in the module being compiled.
17         /// </summary>
18         public class TypeRef : IClassRef {
19
20                 private enum ConversionMethod {
21                         MakeArray,
22                         MakeBoundArray,
23                         MakeManagedPointer,
24                         MakeUnmanagedPointer,
25                         MakeCustomModified
26                 }
27
28                 private Location location;
29                 private string full_name;
30                 private PEAPI.Type resolved_type;
31                 private ArrayList conversion_list;
32                 private bool is_pinned;
33                 private bool is_ref;
34                 private bool is_array;
35
36                 private bool is_resolved;
37
38                 public static readonly TypeRef Ellipsis = new TypeRef ("ELLIPSIS", null);
39                 public static readonly TypeRef Any = new TypeRef ("any", null);
40
41                 public TypeRef (string full_name, Location location)
42                 {
43                         this.full_name = full_name;
44                         this.location = location;
45                         is_pinned = false;
46                         is_ref = false;
47                         is_array = false;
48                         conversion_list = new ArrayList ();
49                         is_resolved = false;
50                 }
51
52                 public string FullName {
53                         get { return full_name; }
54                 }
55
56                 public bool IsPinned {
57                         get { return is_pinned; }
58                 }
59
60                 public bool IsArray {
61                         get { return is_array; }
62                 }
63
64                 public bool IsRef {
65                         get { return is_ref; }
66                 }
67
68                 public PEAPI.Type PeapiType {
69                         get { return resolved_type; }
70                 }
71
72                 public PEAPI.Class PeapiClass {
73                         get { return resolved_type as PEAPI.Class; }
74                 }
75
76                 public bool IsResolved {
77                         get { return is_resolved; }
78                 }
79
80                 public void MakeArray ()
81                 {
82                         conversion_list.Add (ConversionMethod.MakeArray);
83                         is_array = true;
84                 }
85
86                 public void MakeBoundArray (ArrayList bounds)
87                 {
88                         conversion_list.Add (ConversionMethod.MakeBoundArray);
89                         conversion_list.Add (bounds);
90                         is_array = true;
91                 }
92
93                 public void MakeManagedPointer ()
94                 {
95                         conversion_list.Add (ConversionMethod.MakeManagedPointer);
96                         is_ref = true;
97                 }
98
99                 public void MakeUnmanagedPointer ()
100                 {
101                         conversion_list.Add (ConversionMethod.MakeUnmanagedPointer);
102                 }
103
104                 public void MakeCustomModified (CodeGen code_gen, PEAPI.CustomModifier modifier,
105                                 IClassRef klass)
106                 {
107                         conversion_list.Add (ConversionMethod.MakeCustomModified);
108                         conversion_list.Add (klass);
109                         conversion_list.Add (modifier);
110                 }
111
112                 public void MakePinned ()
113                 {
114                         is_pinned = true;
115                 }
116
117                 public  IMethodRef GetMethodRef (ITypeRef ret_type,
118                         PEAPI.CallConv call_conv, string name, ITypeRef[] param)
119                 {
120                         return new MethodRef (this, call_conv, ret_type, name, param);
121                 }
122
123                 public IFieldRef GetFieldRef (ITypeRef ret_type, string name)
124                 {
125                         return new FieldRef (this, ret_type, name);
126                 }
127
128                 public void Resolve (CodeGen code_gen)
129                 {
130                         if (is_resolved)
131                                 return;
132
133                         PEAPI.Type base_type;
134                         PeapiTypeRef peapi_type;
135                         int count = conversion_list.Count;
136
137                         base_type = code_gen.TypeManager.GetPeapiType (full_name);
138
139                         /// TODO: Proper error message
140                         if (base_type == null) {
141                                 Console.WriteLine ("Type not defined: {0} {1}", full_name, location);
142                                 return;
143                         }
144
145                         peapi_type = new PeapiTypeRef (base_type, full_name);
146
147                         for (int i=0; i<count; i++) {
148                                 switch ((ConversionMethod) conversion_list[i]) {
149                                 case ConversionMethod.MakeArray:
150                                         peapi_type.MakeArray ();
151                                         break;
152                                 case ConversionMethod.MakeBoundArray:
153                                         peapi_type.MakeBoundArray ((ArrayList) conversion_list[++i]);
154                                         break;
155                                 case ConversionMethod.MakeManagedPointer:
156                                         peapi_type.MakeManagedPointer ();
157                                         break;
158                                 case ConversionMethod.MakeUnmanagedPointer:
159                                         peapi_type.MakeUnmanagedPointer ();
160                                         break;
161                                 case ConversionMethod.MakeCustomModified:
162                                         peapi_type.MakeCustomModified (code_gen, (PEAPI.CustomModifier) conversion_list[++i],
163                                                 (IClassRef) conversion_list[++i]);
164                                         break;
165                                 }
166                         }
167
168                         resolved_type = peapi_type.PeapiType;
169
170                         is_resolved = true;
171                 }
172
173                 public IClassRef AsClassRef (CodeGen code_gen)
174                 {
175                         return this;
176                 }
177
178                 public override string ToString ()
179                 {
180                         return FullName;
181                 }
182
183         }
184
185 }
186