c5f197b0f5953af7a5f7a855ccaadbf05c89f0c4
[repair.git] / Repair / RepairCompiler / MCC / IR / StructureTypeDescriptor.java
1 package MCC.IR;
2
3 /**
4  * StructureTypeDescriptor
5  *
6  * represents structure types
7  */
8
9 import java.util.*;
10
11 public class StructureTypeDescriptor extends TypeDescriptor {
12
13     TypeDescriptor subtype;
14
15     Hashtable fields = new Hashtable(); /* fast lookups */
16     Vector fieldlist = new Vector(); /* ordering information */
17     Hashtable labels = new Hashtable();
18
19
20     public StructureTypeDescriptor(String name) {
21         super(name);
22     }
23
24     public TypeDescriptor getGenerateType() {
25         return ReservedTypeDescriptor.INT;
26     }
27
28     public Enumeration getFieldKeys() {
29         return fields.keys();
30     }
31     
32     public void setSubClass(boolean b) {
33         this.subclass=b;
34     }
35
36     public Expr getSizeExpr() {
37         return getOffsetExpr(null);
38     }
39
40     Expr sizeexpr=null;
41     Hashtable oexpr=new Hashtable();
42
43     public Expr getOffsetExpr(FieldDescriptor field) {
44         if (field==null) {
45             if (sizeexpr==null) {
46                 sizeexpr=internalgetOffsetExpr(field);
47             } 
48             return sizeexpr;
49         } else if (oexpr.containsKey(field)) {
50             return (Expr)oexpr.get(field);
51         } else {
52             Expr tmp=internalgetOffsetExpr(field);
53             oexpr.put(field,tmp);
54             return tmp;
55         }
56     }
57
58
59     private Expr internalgetOffsetExpr(FieldDescriptor field) {
60         /* Fix sizeof calculations */
61         if ((field==null)&&(subtype!=null)&&(!subclass))
62             return subtype.getSizeExpr();
63
64         boolean aligned=true;
65         Expr size = new IntegerLiteralExpr(0);
66         
67         for (int i = 0; i < fieldlist.size(); i++) {
68             FieldDescriptor fd = (FieldDescriptor)fieldlist.elementAt(i);
69
70             TypeDescriptor td = fd.getType();
71             boolean ptr = fd.getPtr();
72             Expr basesize; 
73             if (ptr) { /* ptrs are 32bits */
74                 basesize = new IntegerLiteralExpr(32);
75             } else {
76                 basesize = td.getSizeExpr();
77             }
78             Expr fieldsize;
79             if (fd instanceof ArrayDescriptor) {
80                 Expr totalsize = new OpExpr(Opcode.MULT, basesize, ((ArrayDescriptor) fd).getIndexBound());
81                 fieldsize=totalsize;
82             } else {
83                 fieldsize=basesize;
84             }
85             if (td instanceof ReservedTypeDescriptor) {
86                 ReservedTypeDescriptor rtd=(ReservedTypeDescriptor) td;
87                 if (rtd==ReservedTypeDescriptor.BIT) {
88                     aligned=false;
89                 } else {
90                     if (!aligned) {
91                         size=new OpExpr(Opcode.RND, size,null);
92                         aligned=true;
93                     }
94                 }
95             } else {
96                 if (!aligned) {
97                     size=new OpExpr(Opcode.RND, size,null);
98                     aligned=true;
99                 }
100             }
101
102             if (fd == field) { /* stop, reached target field */
103                 break;
104             }
105
106             size = new OpExpr(Opcode.ADD, fieldsize, size);
107         }
108
109         if ((field==null)&&(!aligned))
110             return new OpExpr(Opcode.RND, size, null);
111         return size;
112     }
113
114     public Iterator getFields() {
115         return fields.values().iterator();
116     }
117
118     public Iterator getLabels() {
119         return labels.values().iterator();
120     }
121
122     public FieldDescriptor getField(String name) {
123         return (FieldDescriptor) fields.get(name);       
124     }
125
126     public LabelDescriptor getLabel(String name) {
127         return (LabelDescriptor) labels.get(name);
128     }
129
130     public void addField(FieldDescriptor fd) {
131         if (getField(fd.getSymbol()) != null) {
132             throw new IRException("Can not overwrite a field once it has been added.");
133         }        
134         fields.put(fd.getSymbol(), fd);
135         fieldlist.addElement(fd);
136     }
137
138     public void addLabel(LabelDescriptor ld) {
139         if (getLabel(ld.getSymbol()) != null) {
140             throw new IRException("Can not overwrite a label once it has been added.");
141         }
142         labels.put(ld.getSymbol(), ld);
143     }
144
145     public TypeDescriptor getSuperType() {
146         return subtype;
147     }
148
149     public void setSuperType(TypeDescriptor td) {
150         subtype = td;
151     }
152
153     public boolean isSubtypeOf(TypeDescriptor td) {
154         if (td == this) {
155             return true;
156         } else {
157             if (subtype==null)
158                 return false;
159             return subtype.isSubtypeOf(td);
160         }
161     }
162
163     public void generate_printout(CodeWriter cr, VarDescriptor vd) {
164         // #TBD#: does not support printing out fields that have variable size, substructures, etc
165
166         cr.outputline("printf(\"" + getSymbol() + " %p: \", " + vd.getSafeSymbol() + ");");     
167         for (int i = 0; i < fieldlist.size(); i++) {
168             FieldDescriptor fd = (FieldDescriptor) fieldlist.elementAt(i);                                                      
169             cr.outputline("printf(\"\\n\\t" + fd.getSymbol() + " = \");");
170             if (fd.getPtr()) { 
171                 cr.outputline("printf(\"(" + fd.getType().getSymbol() + ") %p \", ((int *)" + vd.getSafeSymbol() + ")[" + i + "]);");
172             } else if ( fd.getType() instanceof ReservedTypeDescriptor) {
173                 cr.outputline("printf(\"%d \", ((int *)" + vd.getSafeSymbol() + ")[" + i + "]);");              
174             } else {
175                 cr.outputline("printf(\"unsupported, breaking\");");
176                 break;
177             }
178         }
179         
180         cr.outputline("printf(\"\\n\");");
181     }
182
183 }