* CodeGen.cs: Add method to resolve global vararg methods.
[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 TypeRef Ellipsis = new TypeRef ("ELLIPSIS", null);
39
40                 public TypeRef (string full_name, Location location)
41                 {
42                         this.full_name = full_name;
43                         this.location = location;
44                         is_pinned = false;
45                         is_ref = false;
46                         is_array = false;
47                         conversion_list = new ArrayList ();
48                         is_resolved = false;
49                 }
50
51                 public string FullName {
52                         get { return full_name; }
53                 }
54
55                 public bool IsPinned {
56                         get { return is_pinned; }
57                 }
58
59                 public bool IsArray {
60                         get { return is_array; }
61                 }
62
63                 public bool IsRef {
64                         get { return is_ref; }
65                 }
66
67                 public PEAPI.Type PeapiType {
68                         get { return resolved_type; }
69                 }
70
71                 public PEAPI.Class PeapiClass {
72                         get { return resolved_type as PEAPI.Class; }
73                 }
74
75                 public bool IsResolved {
76                         get { return is_resolved; }
77                 }
78
79                 public void MakeArray ()
80                 {
81                         conversion_list.Add (ConversionMethod.MakeArray);
82                         is_array = true;
83                 }
84
85                 public void MakeBoundArray (ArrayList bounds)
86                 {
87                         conversion_list.Add (ConversionMethod.MakeBoundArray);
88                         conversion_list.Add (bounds);
89                         is_array = true;
90                 }
91
92                 public void MakeManagedPointer ()
93                 {
94                         conversion_list.Add (ConversionMethod.MakeManagedPointer);
95                         is_ref = true;
96                 }
97
98                 public void MakeUnmanagedPointer ()
99                 {
100                         conversion_list.Add (ConversionMethod.MakeUnmanagedPointer);
101                 }
102
103                 public void MakeCustomModified (PEAPI.CustomModifier modifier)
104                 {
105                         conversion_list.Add (ConversionMethod.MakeCustomModified);
106                         conversion_list.Add (modifier);
107                 }
108
109                 public void MakePinned ()
110                 {
111                         is_pinned = true;
112                 }
113
114                 public  IMethodRef GetMethodRef (ITypeRef ret_type,
115                         PEAPI.CallConv call_conv, string name, ITypeRef[] param)
116                 {
117                         return new MethodRef (this, call_conv, ret_type, name, param);
118                 }
119
120                 public IFieldRef GetFieldRef (ITypeRef ret_type, string name)
121                 {
122                         return new FieldRef (this, ret_type, name);
123                 }
124
125                 public void Resolve (CodeGen code_gen)
126                 {
127                         if (is_resolved)
128                                 return;
129
130                         PEAPI.Type base_type;
131                         PeapiTypeRef peapi_type;
132                         int count = conversion_list.Count;
133
134                         base_type = code_gen.TypeManager.GetPeapiType (full_name);
135
136                         /// TODO: Proper error message
137                         if (base_type == null) {
138                                 Console.WriteLine ("Type not defined: {0} {1}", full_name, location);
139                                 return;
140                         }
141
142                         peapi_type = new PeapiTypeRef (base_type, full_name);
143
144                         for (int i=0; i<count; i++) {
145                                 switch ((ConversionMethod) conversion_list[i]) {
146                                 case ConversionMethod.MakeArray:
147                                         peapi_type.MakeArray ();
148                                         break;
149                                 case ConversionMethod.MakeBoundArray:
150                                         peapi_type.MakeBoundArray ((ArrayList) conversion_list[++i]);
151                                         break;
152                                 case ConversionMethod.MakeManagedPointer:
153                                         peapi_type.MakeManagedPointer ();
154                                         break;
155                                 case ConversionMethod.MakeUnmanagedPointer:
156                                         peapi_type.MakeUnmanagedPointer ();
157                                         break;
158                                 case ConversionMethod.MakeCustomModified:
159                                         peapi_type.MakeCustomModified ((PEAPI.CustomModifier) conversion_list[++i]);
160                                         break;
161                                 }
162                         }
163
164                         resolved_type = peapi_type.PeapiType;
165
166                         is_resolved = true;
167                 }
168
169                 public IClassRef AsClassRef (CodeGen code_gen)
170                 {
171                         return this;
172                 }
173
174                 public override string ToString ()
175                 {
176                         return FullName;
177                 }
178
179         }
180
181 }
182