implemented PCLOC annotation.
[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   private TypeExtension typeExtension;
36
37   public boolean equals(Object o) {
38     if (o instanceof TypeDescriptor) {
39       TypeDescriptor t=(TypeDescriptor)o;
40       if (t.type!=type)
41         return false;
42       if ((type==CLASS)&&(!t.getSymbol().equals(getSymbol())))
43         return false;
44       if (t.arraycount!=arraycount)
45         return false;
46       if (t.isClassNameRef != this.isClassNameRef)
47         return false;
48       return true;
49     }
50     return false;
51   }
52
53   public boolean isString() {
54     if (type!=CLASS)
55       return false;
56     if (arraycount>0)
57       return false;
58     if (!getSymbol().equals(TypeUtil.StringClass))
59       return false;
60     return true;
61   }
62
63   public boolean isClassNameRef() {
64     return this.isClassNameRef;
65   }
66
67   public void setClassNameRef() {
68     this.isClassNameRef = true;
69   }
70
71   public int hashCode() {
72     int hashcode=type^arraycount;
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 if (isNull())
154       return "null";
155     else
156       throw new Error("Error Type: "+type);
157   }
158
159   public String getRepairSymbol() {
160     if (isArray())
161       return IR.Flat.BuildCode.arraytype;
162     else if (isClass()) {
163       return class_desc.getSymbol();
164     } else if (isByte())
165       return "byte";
166     else if (isChar())
167       return "short";
168     else if (isShort())
169       return "short";
170     else if (isEnum())
171       return "int";
172     else if (isInt())
173       return "int";
174     else if (isBoolean())     //Booleans are ints in C
175       return "int";
176     else if (isLong())
177       return "long long";
178     else if (isVoid())
179       return "void";
180     else if (isDouble())
181       return "double";
182     else if (isFloat())
183       return "float";
184     else throw new Error("Error Type: "+type);
185   }
186
187   public String getSafeDescriptor() {
188     //Can't safely use [ in C
189     if (isArray())
190       return "_AR_"+this.dereference().getSafeDescriptor();
191     else if (isClass()||isEnum())
192       return class_desc.getSafeDescriptor();
193     else if (isByte())
194       return "B";
195     else if (isChar())
196       return "C";
197     else if (isShort())
198       return "S";
199     else if (isBoolean())
200       return "Z";
201     else if (isInt())
202       return "I";
203     else if (isLong())
204       return "J";
205     else if (isDouble())
206       return "D";
207     else if (isFloat())
208       return "F";
209     else if (isTag())
210       return "T";
211     else throw new Error(toString());
212   }
213
214   public boolean isNumber() {
215     return (isIntegerType()||isFloat()||isDouble());
216   }
217
218   public boolean isByte() {
219     return type==BYTE;
220   }
221   public boolean isNull() {
222     return type==NULL;
223   }
224   public boolean isShort() {
225     return type==SHORT;
226   }
227   public boolean isInt() {
228     return type==INT;
229   }
230   public boolean isLong() {
231     return type==LONG;
232   }
233   public boolean isChar() {
234     return type==CHAR;
235   }
236   public boolean isBoolean() {
237     return type==BOOLEAN;
238   }
239   public boolean isFloat() {
240     return type==FLOAT;
241   }
242   public boolean isDouble() {
243     return type==DOUBLE;
244   }
245   public boolean isVoid() {
246     return type==VOID;
247   }
248
249   public boolean isOffset() {
250     return type==OFFSET;
251   }
252
253   public boolean isPtr() {
254     return (isClass()||isNull()||isTag()||isArray());
255   }
256
257   public boolean isIntegerType() {
258     return (isInt()||isLong()||isShort()||isChar()||isByte()||isEnum());
259   }
260
261   public void setClassDescriptor(ClassDescriptor cd) {
262     class_desc=cd;
263   }
264
265   public boolean isPrimitive() {
266     return (((type>=BYTE)&&(type<=DOUBLE)) || isEnum());
267   }
268
269   public boolean isEnum() {
270     if(this.type != CLASS) {
271       return false;
272     } else if(this.class_desc != null) {
273       return this.class_desc.isEnum();
274     }
275     return false;
276   }
277
278   public boolean isClass() {
279     return (type==CLASS && !isEnum());
280   }
281
282   public boolean isTag() {
283     return type==TAG;
284   }
285
286   public boolean isImmutable() {
287     return isPrimitive();
288   }
289
290   public TypeDescriptor(NameDescriptor name) {
291     super(name.toString());
292     this.type=CLASS;
293     this.class_desc=null;
294     this.arraycount=0;
295     this.isClassNameRef =false;
296     this.annotationSet=new Vector<AnnotationDescriptor>();
297   }
298
299   public TypeDescriptor(String st) {
300     super(st);
301     this.type=CLASS;
302     this.class_desc=null;
303     this.arraycount=0;
304     this.isClassNameRef =false;
305     this.annotationSet=new Vector<AnnotationDescriptor>();
306   }
307
308   public ClassDescriptor getClassDesc() {
309     return class_desc;
310   }
311
312   public TypeDescriptor(ClassDescriptor cd) {
313     super(cd.getSymbol());
314     this.type=CLASS;
315     this.class_desc=cd;
316     this.arraycount=0;
317     this.isClassNameRef =false;
318     this.annotationSet=new Vector<AnnotationDescriptor>();
319   }
320
321   public TypeDescriptor(int t) {
322     super(decodeInt(t));
323     this.type=t;
324     this.arraycount=0;
325     this.isClassNameRef =false;
326     this.annotationSet=new Vector<AnnotationDescriptor>();
327   }
328
329   public String toString() {
330     if (type==CLASS) {
331       return name;
332     } else
333       return decodeInt(type);
334   }
335
336   public String toPrettyString() {
337     String str=name;
338     if (type!=CLASS) {
339       str=decodeInt(type);
340     }
341     for(int i=0; i<arraycount; i++)
342       str+="[]";
343     return str;
344   }
345
346   private static String decodeInt(int type) {
347     if (type==BYTE)
348       return "byte";
349     else if (type==BOOLEAN)
350       return "boolean";
351     else if (type==SHORT)
352       return "short";
353     else if (type==INT)
354       return "int";
355     else if (type==LONG)
356       return "long";
357     else if (type==CHAR)
358       return "char";
359     else if (type==FLOAT)
360       return "float";
361     else if (type==DOUBLE)
362       return "double";
363     else if (type==VOID)
364       return "void";
365     else if (type==NULL)
366       return "NULL";
367     else if (type==TAG)
368       return TypeUtil.TagClass;
369     else if (type==OFFSET)
370       return "offset";
371     else throw new Error();
372   }
373
374   public void addAnnotationMarker(AnnotationDescriptor an) {
375     annotationSet.add(an);
376   }
377
378   public Vector<AnnotationDescriptor> getAnnotationMarkers() {
379     return annotationSet;
380   }
381
382   public void setExtension(TypeExtension te) {
383     typeExtension=te;
384   }
385
386   public TypeExtension getExtension() {
387     return typeExtension;
388   }
389
390 }