introduce new flag -ssjava for enabling SSJava feature and start working on the imple...
[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     if (type==CLASS)
73       hashcode^=getSymbol().hashCode();
74     return hashcode;
75   }
76
77   public boolean iswrapper() {
78     if (arraycount!=0||!isClass())
79       return false;
80     return (name.equals("bytewrapper")||
81             name.equals("booleanwrapper")||
82             name.equals("shortwrapper")||
83             name.equals("intwrapper")||
84             name.equals("longwrapper")||
85             name.equals("charwrapper")||
86             name.equals("floatwrapper")||
87             name.equals("doublewrapper")||
88             name.equals("Objectwrapper"));
89   }
90
91   public TypeDescriptor makeArray(State state) {
92     TypeDescriptor td=new TypeDescriptor(getSymbol());
93     td.arraycount=arraycount+1;
94     td.type=type;
95     td.class_desc=class_desc;
96     state.addArrayType(td);
97     return td;
98   }
99
100   public boolean isArray() {
101     return (arraycount>0);
102   }
103
104   public int getArrayCount() {
105     return arraycount;
106   }
107
108   /* Only use this method if you really know what you are doing.  It
109    * doesn't have the effect you might expect. */
110
111   public void setArrayCount(int a) {
112     arraycount=a;
113   }
114
115   public TypeDescriptor dereference() {
116     TypeDescriptor td=new TypeDescriptor(getSymbol());
117     if (arraycount==0)
118       throw new Error();
119     td.arraycount=arraycount-1;
120     td.type=type;
121     td.class_desc=class_desc;
122     return td;
123   }
124
125   public String getSafeSymbol() {
126     if (isArray())
127       return IR.Flat.BuildCode.arraytype;
128     else if (isClass()) {
129       return class_desc.getSafeSymbol();
130     } else if (isByte())
131       return "char";
132     else if (isChar())
133       return "short";
134     else if (isShort())
135       return "short";
136     else if (isInt())
137       return "int";
138     else if (isBoolean())     //Booleans are ints in C
139       return "int";
140     else if (isLong())
141       return "long long";
142     else if (isVoid())
143       return "void";
144     else if (isDouble())
145       return "double";
146     else if (isFloat())
147       return "float";
148     else if (isOffset())
149       return "short";
150     else 
151       throw new Error("Error Type: "+type);
152   }
153
154   public String getRepairSymbol() {
155     if (isArray())
156       return IR.Flat.BuildCode.arraytype;
157     else if (isClass()) {
158       return class_desc.getSymbol();
159     } else if (isByte())
160       return "byte";
161     else if (isChar())
162       return "short";
163     else if (isShort())
164       return "short";
165     else if (isInt())
166       return "int";
167     else if (isBoolean())     //Booleans are ints in C
168       return "int";
169     else if (isLong())
170       return "long long";
171     else if (isVoid())
172       return "void";
173     else if (isDouble())
174       return "double";
175     else if (isFloat())
176       return "float";
177     else throw new Error("Error Type: "+type);
178   }
179
180   public String getSafeDescriptor() {
181     //Can't safely use [ in C
182     if (isArray())
183       return "_AR_"+this.dereference().getSafeDescriptor();
184     else if (isClass())
185       return class_desc.getSafeDescriptor();
186     else if (isByte())
187       return "B";
188     else if (isChar())
189       return "C";
190     else if (isShort())
191       return "S";
192     else if (isBoolean())
193       return "Z";
194     else if (isInt())
195       return "I";
196     else if (isLong())
197       return "J";
198     else if (isDouble())
199       return "D";
200     else if (isFloat())
201       return "F";
202     else if (isTag())
203       return "T";
204     else throw new Error();
205   }
206
207   public boolean isNumber() {
208     return (isIntegerType()||isFloat()||isDouble());
209   }
210
211   public boolean isByte() {
212     return type==BYTE;
213   }
214   public boolean isNull() {
215     return type==NULL;
216   }
217   public boolean isShort() {
218     return type==SHORT;
219   }
220   public boolean isInt() {
221     return type==INT;
222   }
223   public boolean isLong() {
224     return type==LONG;
225   }
226   public boolean isChar() {
227     return type==CHAR;
228   }
229   public boolean isBoolean() {
230     return type==BOOLEAN;
231   }
232   public boolean isFloat() {
233     return type==FLOAT;
234   }
235   public boolean isDouble() {
236     return type==DOUBLE;
237   }
238   public boolean isVoid() {
239     return type==VOID;
240   }
241
242   public boolean isOffset() {
243     return type==OFFSET;
244   }
245
246   public boolean isPtr() {
247     return ((isClass()&&!isEnum())||isNull()||isTag()||isArray());
248   }
249
250   public boolean isIntegerType() {
251     return (isInt()||isLong()||isShort()||isChar()||isByte()||isEnum());
252   }
253
254   public void setClassDescriptor(ClassDescriptor cd) {
255     class_desc=cd;
256   }
257
258   public boolean isPrimitive() {
259     return ((type>=BYTE)&&(type<=DOUBLE));
260   }
261
262   public boolean isEnum() {
263     if(this.type != CLASS) {
264       return false;
265     } else if(this.class_desc != null){
266       return this.class_desc.isEnum();
267     }
268     return false;
269   }
270   
271   public boolean isClass() {
272     return type==CLASS;
273   }
274
275   public boolean isTag() {
276     return type==TAG;
277   }
278
279   public boolean isImmutable() {
280     return isPrimitive() || isString();
281   }
282
283   public TypeDescriptor(NameDescriptor name) {
284     super(name.toString());
285     this.type=CLASS;
286     this.class_desc=null;
287     this.arraycount=0;
288     this.isClassNameRef =false;
289     this.annotationSet=new Vector<AnnotationDescriptor>();
290   }
291
292   public TypeDescriptor(String st) {
293     super(st);
294     this.type=CLASS;
295     this.class_desc=null;
296     this.arraycount=0;
297     this.isClassNameRef =false;
298     this.annotationSet=new Vector<AnnotationDescriptor>();
299   }
300
301   public ClassDescriptor getClassDesc() {
302     return class_desc;
303   }
304
305   public TypeDescriptor(ClassDescriptor cd) {
306     super(cd.getSymbol());
307     this.type=CLASS;
308     this.class_desc=cd;
309     this.arraycount=0;
310     this.isClassNameRef =false;
311     this.annotationSet=new Vector<AnnotationDescriptor>();
312   }
313
314   public TypeDescriptor(int t) {
315     super(decodeInt(t));
316     this.type=t;
317     this.arraycount=0;
318     this.isClassNameRef =false;
319     this.annotationSet=new Vector<AnnotationDescriptor>();
320   }
321
322   public String toString() {
323     if (type==CLASS) {
324       return name;
325     } else
326       return decodeInt(type);
327   }
328
329   public String toPrettyString() {
330     String str=name;
331     if (type!=CLASS) {
332       str=decodeInt(type);
333     }
334     for(int i=0; i<arraycount; i++)
335       str+="[]";
336     return str;    
337   }
338
339   private static String decodeInt(int type) {
340     if (type==BYTE)
341       return "byte";
342     else if (type==BOOLEAN)
343       return "boolean";
344     else if (type==SHORT)
345       return "short";
346     else if (type==INT)
347       return "int";
348     else if (type==LONG)
349       return "long";
350     else if (type==CHAR)
351       return "char";
352     else if (type==FLOAT)
353       return "float";
354     else if (type==DOUBLE)
355       return "double";
356     else if (type==VOID)
357       return "void";
358     else if (type==NULL)
359       return "NULL";
360     else if (type==TAG)
361       return TypeUtil.TagClass;
362     else if (type==OFFSET)
363       return "offset";
364     else throw new Error();
365   }
366   
367   public void addAnnotationMarker(AnnotationDescriptor an){
368     annotationSet.add(an);
369   }
370   
371   public Vector<AnnotationDescriptor> getAnnotationMarkers(){
372     return annotationSet;
373   }
374   
375 }