Fixed Dan's confusion regarding alignment of fields. Modified the
[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     public StructureTypeDescriptor(String name) {
20         super(name);
21     }
22
23     public TypeDescriptor getGenerateType() {
24         return ReservedTypeDescriptor.INT;
25     }
26
27     public Enumeration getFieldKeys() {
28         return fields.keys();
29     }
30    
31     
32     public Expr getSizeExpr() {        
33         return getOffsetExpr(null);
34     }
35
36     public Expr getOffsetExpr(FieldDescriptor field) {
37         
38         boolean aligned=true;
39         Expr size = new IntegerLiteralExpr(0);
40         
41         for (int i = 0; i < fieldlist.size(); i++) {
42             FieldDescriptor fd = (FieldDescriptor)fieldlist.elementAt(i);
43
44             TypeDescriptor td = fd.getType();
45             boolean ptr = fd.getPtr();
46             Expr basesize; 
47             if (ptr) { /* ptrs are 32bits */
48                 
49                 basesize = new IntegerLiteralExpr(32);
50             } else {
51                 basesize = td.getSizeExpr();
52             }
53             Expr fieldsize;
54             if (fd instanceof ArrayDescriptor) {
55                 Expr totalsize = new OpExpr(Opcode.MULT, basesize, ((ArrayDescriptor) fd).getIndexBound());
56                 fieldsize=totalsize;
57             } else {
58                 fieldsize=basesize;
59             }
60             if (td instanceof ReservedTypeDescriptor) {
61                 ReservedTypeDescriptor rtd=(ReservedTypeDescriptor) td;
62                 if (rtd==ReservedTypeDescriptor.BIT) {
63                     aligned=false;
64                 } else {
65                     if (!aligned) {
66                         size=new OpExpr(Opcode.RND, size,null);
67                         aligned=true;
68                     }
69                 }
70             } else {
71                 if (!aligned) {
72                     size=new OpExpr(Opcode.RND, size,null);
73                     aligned=true;
74                 }
75             }
76
77             if (fd == field) { /* stop, reached target field */
78                 break; 
79             }
80
81             size = new OpExpr(Opcode.ADD, fieldsize, size);
82         }
83
84         if ((field==null)&&(!aligned))
85             return new OpExpr(Opcode.RND, size, null);
86         return size;
87     }
88
89     public Iterator getFields() {
90         return fields.values().iterator();
91     }
92
93     public Iterator getLabels() {
94         return labels.values().iterator();
95     }
96
97     public FieldDescriptor getField(String name) {
98         return (FieldDescriptor) fields.get(name);       
99     }
100
101     public LabelDescriptor getLabel(String name) {
102         return (LabelDescriptor) labels.get(name);
103     }
104
105     public void addField(FieldDescriptor fd) {
106         if (getField(fd.getSymbol()) != null) {
107             throw new IRException("Can not overwrite a field once it has been added.");
108         }        
109         fields.put(fd.getSymbol(), fd);
110         fieldlist.addElement(fd);
111     }
112
113     public void addLabel(LabelDescriptor ld) {
114         if (getLabel(ld.getSymbol()) != null) {
115             throw new IRException("Can not overwrite a label once it has been added.");
116         }
117         labels.put(ld.getSymbol(), ld);
118     }
119
120     public TypeDescriptor getSubType() {
121         return subtype;
122     }
123
124     public void setSubType(TypeDescriptor td) {
125         subtype = td;
126     }
127
128     public boolean isSubtypeOf(TypeDescriptor td) {
129         if (td == this) {
130             return true;
131         } else {
132             return subtype.isSubtypeOf(td);
133         }
134     }
135
136 }