keep the current snapshot before making further changes.
[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 (isInt())
138       return "int";
139     else if (isBoolean())     //Booleans are ints in C
140       return "int";
141     else if (isLong())
142       return "long long";
143     else if (isVoid())
144       return "void";
145     else if (isDouble())
146       return "double";
147     else if (isFloat())
148       return "float";
149     else if (isOffset())
150       return "short";
151     else 
152       throw new Error("Error Type: "+type);
153   }
154
155   public String getRepairSymbol() {
156     if (isArray())
157       return IR.Flat.BuildCode.arraytype;
158     else if (isClass()) {
159       return class_desc.getSymbol();
160     } else if (isByte())
161       return "byte";
162     else if (isChar())
163       return "short";
164     else if (isShort())
165       return "short";
166     else if (isInt())
167       return "int";
168     else if (isBoolean())     //Booleans are ints in C
169       return "int";
170     else if (isLong())
171       return "long long";
172     else if (isVoid())
173       return "void";
174     else if (isDouble())
175       return "double";
176     else if (isFloat())
177       return "float";
178     else throw new Error("Error Type: "+type);
179   }
180
181   public String getSafeDescriptor() {
182     //Can't safely use [ in C
183     if (isArray())
184       return "_AR_"+this.dereference().getSafeDescriptor();
185     else if (isClass())
186       return class_desc.getSafeDescriptor();
187     else if (isByte())
188       return "B";
189     else if (isChar())
190       return "C";
191     else if (isShort())
192       return "S";
193     else if (isBoolean())
194       return "Z";
195     else if (isInt())
196       return "I";
197     else if (isLong())
198       return "J";
199     else if (isDouble())
200       return "D";
201     else if (isFloat())
202       return "F";
203     else if (isTag())
204       return "T";
205     else throw new Error();
206   }
207
208   public boolean isNumber() {
209     return (isIntegerType()||isFloat()||isDouble());
210   }
211
212   public boolean isByte() {
213     return type==BYTE;
214   }
215   public boolean isNull() {
216     return type==NULL;
217   }
218   public boolean isShort() {
219     return type==SHORT;
220   }
221   public boolean isInt() {
222     return type==INT;
223   }
224   public boolean isLong() {
225     return type==LONG;
226   }
227   public boolean isChar() {
228     return type==CHAR;
229   }
230   public boolean isBoolean() {
231     return type==BOOLEAN;
232   }
233   public boolean isFloat() {
234     return type==FLOAT;
235   }
236   public boolean isDouble() {
237     return type==DOUBLE;
238   }
239   public boolean isVoid() {
240     return type==VOID;
241   }
242
243   public boolean isOffset() {
244     return type==OFFSET;
245   }
246
247   public boolean isPtr() {
248     return ((isClass()&&!isEnum())||isNull()||isTag()||isArray());
249   }
250
251   public boolean isIntegerType() {
252     return (isInt()||isLong()||isShort()||isChar()||isByte()||isEnum());
253   }
254
255   public void setClassDescriptor(ClassDescriptor cd) {
256     class_desc=cd;
257   }
258
259   public boolean isPrimitive() {
260     return ((type>=BYTE)&&(type<=DOUBLE));
261   }
262
263   public boolean isEnum() {
264     if(this.type != CLASS) {
265       return false;
266     } else if(this.class_desc != null){
267       return this.class_desc.isEnum();
268     }
269     return false;
270   }
271   
272   public boolean isClass() {
273     return type==CLASS;
274   }
275
276   public boolean isTag() {
277     return type==TAG;
278   }
279
280   public boolean isImmutable() {
281     return isPrimitive() || isString();
282   }
283
284   public TypeDescriptor(NameDescriptor name) {
285     super(name.toString());
286     this.type=CLASS;
287     this.class_desc=null;
288     this.arraycount=0;
289     this.isClassNameRef =false;
290     this.annotationSet=new Vector<AnnotationDescriptor>();
291   }
292
293   public TypeDescriptor(String st) {
294     super(st);
295     this.type=CLASS;
296     this.class_desc=null;
297     this.arraycount=0;
298     this.isClassNameRef =false;
299     this.annotationSet=new Vector<AnnotationDescriptor>();
300   }
301
302   public ClassDescriptor getClassDesc() {
303     return class_desc;
304   }
305
306   public TypeDescriptor(ClassDescriptor cd) {
307     super(cd.getSymbol());
308     this.type=CLASS;
309     this.class_desc=cd;
310     this.arraycount=0;
311     this.isClassNameRef =false;
312     this.annotationSet=new Vector<AnnotationDescriptor>();
313   }
314
315   public TypeDescriptor(int t) {
316     super(decodeInt(t));
317     this.type=t;
318     this.arraycount=0;
319     this.isClassNameRef =false;
320     this.annotationSet=new Vector<AnnotationDescriptor>();
321   }
322
323   public String toString() {
324     if (type==CLASS) {
325       return name;
326     } else
327       return decodeInt(type);
328   }
329
330   public String toPrettyString() {
331     String str=name;
332     if (type!=CLASS) {
333       str=decodeInt(type);
334     }
335     for(int i=0; i<arraycount; i++)
336       str+="[]";
337     return str;    
338   }
339
340   private static String decodeInt(int type) {
341     if (type==BYTE)
342       return "byte";
343     else if (type==BOOLEAN)
344       return "boolean";
345     else if (type==SHORT)
346       return "short";
347     else if (type==INT)
348       return "int";
349     else if (type==LONG)
350       return "long";
351     else if (type==CHAR)
352       return "char";
353     else if (type==FLOAT)
354       return "float";
355     else if (type==DOUBLE)
356       return "double";
357     else if (type==VOID)
358       return "void";
359     else if (type==NULL)
360       return "NULL";
361     else if (type==TAG)
362       return TypeUtil.TagClass;
363     else if (type==OFFSET)
364       return "offset";
365     else throw new Error();
366   }
367   
368   public void addAnnotationMarker(AnnotationDescriptor an){
369     annotationSet.add(an);
370   }
371   
372   public Vector<AnnotationDescriptor> getAnnotationMarkers(){
373     return annotationSet;
374   }
375   
376 }