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