bug...wonder how this used to work??
[IRC.git] / Robust / src / IR / TypeDescriptor.java
1 package IR;
2
3 import java.util.HashSet;
4 import java.util.Set;
5 import java.util.Vector;
6
7 /**
8  * Descriptor
9  *
10  * represents a symbol in the language (var name, function name, etc).
11  */
12
13 public class TypeDescriptor extends Descriptor {
14   public static final int BYTE=1;
15   public static final int SHORT=2;
16   public static final int INT=3;
17   public static final int LONG=4;
18   public static final int CHAR=5;
19   public static final int BOOLEAN=6;
20   public static final int FLOAT=7;
21   public static final int DOUBLE=8;
22   public static final int VOID=9;
23   public static final int NULL=10;
24   public static final int TAG=11;
25   public static final int CLASS=12;
26   public static final int OFFSET=13;
27
28
29   int arraycount;
30   private int type;
31   ClassDescriptor class_desc;
32   boolean isClassNameRef = false;
33   
34   private Vector<AnnotationDescriptor> annotationSet;
35
36   public boolean equals(Object o) {
37     if (o instanceof TypeDescriptor) {
38       TypeDescriptor t=(TypeDescriptor)o;
39       if (t.type!=type)
40         return false;
41       if ((type==CLASS)&&(!t.getSymbol().equals(getSymbol())))
42         return false;
43       if (t.arraycount!=arraycount)
44         return false;
45       if (t.isClassNameRef != this.isClassNameRef)
46         return false;
47       return true;
48     }
49     return false;
50   }
51
52   public boolean isString() {
53     if (type!=CLASS)
54       return false;
55     if (arraycount>0)
56       return false;
57     if (!getSymbol().equals(TypeUtil.StringClass))
58       return false;
59     return true;
60   }
61   
62   public boolean isClassNameRef() {
63     return this.isClassNameRef;
64   }
65   
66   public void setClassNameRef() {
67     this.isClassNameRef = true;
68   }
69
70   public int hashCode() {
71     int hashcode=type^arraycount;
72     hashcode+=annotationSet.hashCode();
73     if (type==CLASS)
74       hashcode^=getSymbol().hashCode();
75     return hashcode;
76   }
77
78   public boolean iswrapper() {
79     if (arraycount!=0||!isClass())
80       return false;
81     return (name.equals("bytewrapper")||
82             name.equals("booleanwrapper")||
83             name.equals("shortwrapper")||
84             name.equals("intwrapper")||
85             name.equals("longwrapper")||
86             name.equals("charwrapper")||
87             name.equals("floatwrapper")||
88             name.equals("doublewrapper")||
89             name.equals("Objectwrapper"));
90   }
91
92   public TypeDescriptor makeArray(State state) {
93     TypeDescriptor td=new TypeDescriptor(getSymbol());
94     td.arraycount=arraycount+1;
95     td.type=type;
96     td.class_desc=class_desc;
97     state.addArrayType(td);
98     return td;
99   }
100
101   public boolean isArray() {
102     return (arraycount>0);
103   }
104
105   public int getArrayCount() {
106     return arraycount;
107   }
108
109   /* Only use this method if you really know what you are doing.  It
110    * doesn't have the effect you might expect. */
111
112   public void setArrayCount(int a) {
113     arraycount=a;
114   }
115
116   public TypeDescriptor dereference() {
117     TypeDescriptor td=new TypeDescriptor(getSymbol());
118     if (arraycount==0)
119       throw new Error();
120     td.arraycount=arraycount-1;
121     td.type=type;
122     td.class_desc=class_desc;
123     return td;
124   }
125
126   public String getSafeSymbol() {
127     if (isArray())
128       return IR.Flat.BuildCode.arraytype;
129     else if (isClass()) {
130       return class_desc.getSafeSymbol();
131     } else if (isByte())
132       return "char";
133     else if (isChar())
134       return "short";
135     else if (isShort())
136       return "short";
137     else if (isEnum())
138       return "int";
139     else if (isInt())
140       return "int";
141     else if (isBoolean())     //Booleans are ints in C
142       return "int";
143     else if (isLong())
144       return "long long";
145     else if (isVoid())
146       return "void";
147     else if (isDouble())
148       return "double";
149     else if (isFloat())
150       return "float";
151     else if (isOffset())
152       return "short";
153     else 
154       throw new Error("Error Type: "+type);
155   }
156
157   public String getRepairSymbol() {
158     if (isArray())
159       return IR.Flat.BuildCode.arraytype;
160     else if (isClass()) {
161       return class_desc.getSymbol();
162     } else if (isByte())
163       return "byte";
164     else if (isChar())
165       return "short";
166     else if (isShort())
167       return "short";
168     else if (isEnum())
169       return "int";
170     else if (isInt())
171       return "int";
172     else if (isBoolean())     //Booleans are ints in C
173       return "int";
174     else if (isLong())
175       return "long long";
176     else if (isVoid())
177       return "void";
178     else if (isDouble())
179       return "double";
180     else if (isFloat())
181       return "float";
182     else throw new Error("Error Type: "+type);
183   }
184
185   public String getSafeDescriptor() {
186     //Can't safely use [ in C
187     if (isArray())
188       return "_AR_"+this.dereference().getSafeDescriptor();
189     else if (isClass()||isEnum())
190       return class_desc.getSafeDescriptor();
191     else if (isByte())
192       return "B";
193     else if (isChar())
194       return "C";
195     else if (isShort())
196       return "S";
197     else if (isBoolean())
198       return "Z";
199     else if (isInt())
200       return "I";
201     else if (isLong())
202       return "J";
203     else if (isDouble())
204       return "D";
205     else if (isFloat())
206       return "F";
207     else if (isTag())
208       return "T";
209     else throw new Error(toString());
210   }
211
212   public boolean isNumber() {
213     return (isIntegerType()||isFloat()||isDouble());
214   }
215
216   public boolean isByte() {
217     return type==BYTE;
218   }
219   public boolean isNull() {
220     return type==NULL;
221   }
222   public boolean isShort() {
223     return type==SHORT;
224   }
225   public boolean isInt() {
226     return type==INT;
227   }
228   public boolean isLong() {
229     return type==LONG;
230   }
231   public boolean isChar() {
232     return type==CHAR;
233   }
234   public boolean isBoolean() {
235     return type==BOOLEAN;
236   }
237   public boolean isFloat() {
238     return type==FLOAT;
239   }
240   public boolean isDouble() {
241     return type==DOUBLE;
242   }
243   public boolean isVoid() {
244     return type==VOID;
245   }
246
247   public boolean isOffset() {
248     return type==OFFSET;
249   }
250
251   public boolean isPtr() {
252     return (isClass()||isNull()||isTag()||isArray());
253   }
254
255   public boolean isIntegerType() {
256     return (isInt()||isLong()||isShort()||isChar()||isByte()||isEnum());
257   }
258
259   public void setClassDescriptor(ClassDescriptor cd) {
260     class_desc=cd;
261   }
262
263   public boolean isPrimitive() {
264     return (((type>=BYTE)&&(type<=DOUBLE)) || isEnum());
265   }
266
267   public boolean isEnum() {
268     if(this.type != CLASS) {
269       return false;
270     } else if(this.class_desc != null){
271       return this.class_desc.isEnum();
272     }
273     return false;
274   }
275   
276   public boolean isClass() {
277     return (type==CLASS && !isEnum());
278   }
279
280   public boolean isTag() {
281     return type==TAG;
282   }
283
284   public boolean isImmutable() {
285     return isPrimitive() || isString();
286   }
287
288   public TypeDescriptor(NameDescriptor name) {
289     super(name.toString());
290     this.type=CLASS;
291     this.class_desc=null;
292     this.arraycount=0;
293     this.isClassNameRef =false;
294     this.annotationSet=new Vector<AnnotationDescriptor>();
295   }
296
297   public TypeDescriptor(String st) {
298     super(st);
299     this.type=CLASS;
300     this.class_desc=null;
301     this.arraycount=0;
302     this.isClassNameRef =false;
303     this.annotationSet=new Vector<AnnotationDescriptor>();
304   }
305
306   public ClassDescriptor getClassDesc() {
307     return class_desc;
308   }
309
310   public TypeDescriptor(ClassDescriptor cd) {
311     super(cd.getSymbol());
312     this.type=CLASS;
313     this.class_desc=cd;
314     this.arraycount=0;
315     this.isClassNameRef =false;
316     this.annotationSet=new Vector<AnnotationDescriptor>();
317   }
318
319   public TypeDescriptor(int t) {
320     super(decodeInt(t));
321     this.type=t;
322     this.arraycount=0;
323     this.isClassNameRef =false;
324     this.annotationSet=new Vector<AnnotationDescriptor>();
325   }
326
327   public String toString() {
328     if (type==CLASS) {
329       return name;
330     } else
331       return decodeInt(type);
332   }
333
334   public String toPrettyString() {
335     String str=name;
336     if (type!=CLASS) {
337       str=decodeInt(type);
338     }
339     for(int i=0; i<arraycount; i++)
340       str+="[]";
341     return str;    
342   }
343
344   private static String decodeInt(int type) {
345     if (type==BYTE)
346       return "byte";
347     else if (type==BOOLEAN)
348       return "boolean";
349     else if (type==SHORT)
350       return "short";
351     else if (type==INT)
352       return "int";
353     else if (type==LONG)
354       return "long";
355     else if (type==CHAR)
356       return "char";
357     else if (type==FLOAT)
358       return "float";
359     else if (type==DOUBLE)
360       return "double";
361     else if (type==VOID)
362       return "void";
363     else if (type==NULL)
364       return "NULL";
365     else if (type==TAG)
366       return TypeUtil.TagClass;
367     else if (type==OFFSET)
368       return "offset";
369     else throw new Error();
370   }
371   
372   public void addAnnotationMarker(AnnotationDescriptor an){
373     annotationSet.add(an);
374   }
375   
376   public Vector<AnnotationDescriptor> getAnnotationMarkers(){
377     return annotationSet;
378   }
379   
380 }