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