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