[mini] Use C++ linker iff building C++ that needs the C++ runtime (#12266)
[mono-project.git] / mcs / ilasm / codegen / ModifiableType.cs
blob24bd9391579938637d8c20e6f9c14205f7cbc577
1 //
2 // Mono.ILASM.ModifiableType
3 //
4 // Author(s):
5 // Jackson Harper (Jackson@LatitudeGeo.com)
6 //
7 // (C) 2003 Jackson Harper (Jackson@LatitudeGeo.com)
8 //
11 using System;
12 using System.Collections;
14 namespace Mono.ILASM {
16 public abstract class ModifiableType {
18 private ArrayList conversion_list;
19 private bool is_pinned;
20 private bool is_ref;
21 private bool is_array;
22 private bool use_type_spec;
24 private enum ConversionMethod {
25 MakeArray,
26 MakeBoundArray,
27 MakeManagedPointer,
28 MakeUnmanagedPointer,
29 MakeCustomModified
32 public ModifiableType ()
34 conversion_list = new ArrayList (5);
37 public abstract string SigMod {
38 get;
39 set;
42 protected ArrayList ConversionList {
43 get { return conversion_list; }
44 set { conversion_list = value; }
47 public bool IsPinned {
48 get { return is_pinned; }
51 public bool IsArray {
52 get { return is_array; }
55 public bool IsRef {
56 get { return is_ref; }
59 public bool UseTypeSpec {
60 get { return use_type_spec; }
63 public void MakeArray ()
65 use_type_spec = true;
66 conversion_list.Add (ConversionMethod.MakeArray);
67 is_array = true;
68 SigMod += "[]";
71 public void MakeBoundArray (ArrayList bounds)
73 use_type_spec = true;
74 conversion_list.Add (ConversionMethod.MakeBoundArray);
75 conversion_list.Add (bounds);
76 is_array = true;
77 SigMod += "[";
78 for (int i=0; i<bounds.Count; i++) {
79 DictionaryEntry e = (DictionaryEntry) bounds [i];
80 if (e.Key != TypeRef.Ellipsis)
81 SigMod += e.Key;
82 SigMod += "...";
83 if (e.Value != TypeRef.Ellipsis)
84 SigMod += e.Value;
85 if (i + 1 < bounds.Count)
86 SigMod += ", ";
88 SigMod += "]";
91 public void MakeManagedPointer ()
93 use_type_spec = true;
94 conversion_list.Add (ConversionMethod.MakeManagedPointer);
95 is_ref = true;
96 SigMod += "&";
99 public void MakeUnmanagedPointer ()
101 use_type_spec = true;
102 conversion_list.Add (ConversionMethod.MakeUnmanagedPointer);
103 SigMod += "*";
106 public void MakeCustomModified (CodeGen code_gen, PEAPI.CustomModifier modifier,
107 BaseTypeRef klass)
109 use_type_spec = true;
110 conversion_list.Add (ConversionMethod.MakeCustomModified);
111 conversion_list.Add (modifier);
112 conversion_list.Add (klass);
114 if (modifier == PEAPI.CustomModifier.modreq)
115 SigMod += ("modreq (" + klass.FullName + ")");
116 else if (modifier == PEAPI.CustomModifier.modopt)
117 SigMod += ("modopt (" + klass.FullName + ")");
120 public void MakePinned ()
122 use_type_spec = true;
123 is_pinned = true;
126 protected PEAPI.Type Modify (CodeGen code_gen, PEAPI.Type type)
128 PeapiTypeRef peapi_type = new PeapiTypeRef (type);
129 int count = conversion_list.Count;
130 for (int i=0; i<count; i++) {
131 switch ((ConversionMethod) conversion_list[i]) {
132 case ConversionMethod.MakeArray:
133 peapi_type.MakeArray ();
134 break;
135 case ConversionMethod.MakeBoundArray:
136 peapi_type.MakeBoundArray ((ArrayList) conversion_list[++i]);
137 break;
138 case ConversionMethod.MakeManagedPointer:
139 peapi_type.MakeManagedPointer ();
140 break;
141 case ConversionMethod.MakeUnmanagedPointer:
142 peapi_type.MakeUnmanagedPointer ();
143 break;
144 case ConversionMethod.MakeCustomModified:
145 peapi_type.MakeCustomModified (code_gen, (PEAPI.CustomModifier) conversion_list[++i],
146 (BaseTypeRef) conversion_list[++i]);
147 break;
152 return peapi_type.PeapiType;