7296606a1da912945afa51978a528bd6157d167b
[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     private Vector getFieldSizes() {
32         Vector fieldsizes = new Vector();
33                 
34         for (int i = 0; i < fieldlist.size(); i++) {
35             FieldDescriptor fd = (FieldDescriptor) fieldlist.elementAt(i);
36             TypeDescriptor td = fd.getType();
37             boolean ptr = fd.getPtr();
38
39             Expr basesize; 
40             if (ptr) { /* ptrs are 32bits */
41                 basesize = new IntegerLiteralExpr(32);
42             } else {
43                 basesize = td.getSizeExpr();
44             }
45
46             if (fd instanceof ArrayDescriptor) {
47                 Expr totalsize = new OpExpr(Opcode.MULT, basesize, ((ArrayDescriptor) fd).getIndexBound());
48                 fieldsizes.addElement(totalsize);
49             } else {
50                 fieldsizes.addElement(basesize);
51             }
52         }
53
54         return fieldsizes;
55     }
56     
57     public Expr getSizeExpr() {        
58         Vector fieldsizes = getFieldSizes();
59
60         /* we've got the field sizes! now return the addition! */
61         Expr size = new IntegerLiteralExpr(0);
62         
63         for (int i = 0; i < fieldsizes.size(); i++) {
64             Expr fieldsize = (Expr) fieldsizes.elementAt(i);
65             size = new OpExpr(Opcode.ADD, fieldsize, size);
66         }
67         
68         return size;
69     }
70
71     public Expr getOffsetExpr(FieldDescriptor field) {
72         Vector fieldsizes = getFieldSizes();
73
74         // #ATTN#: getOffsetExpr needs to be called with the fielddescriptor obect that is in teh vector list
75         // this means that if the field is an arraydescriptor you have to call getOffsetExpr with the array 
76
77         /* we've got the field sizes! now return the addition! */
78         Expr size = new IntegerLiteralExpr(0);
79         
80         for (int i = 0; i < fieldsizes.size(); i++) {
81             FieldDescriptor fd = (FieldDescriptor)fieldlist.elementAt(i);
82
83             if (fd == field) { /* stop, reached target field */
84                 break; 
85             }
86
87             Expr fieldsize = (Expr) fieldsizes.elementAt(i);
88             size = new OpExpr(Opcode.ADD, fieldsize, size);
89         }
90         
91         return size;
92     }
93
94     public Iterator getFields() {
95         return fields.values().iterator();
96     }
97
98     public Iterator getLabels() {
99         return labels.values().iterator();
100     }
101
102     public FieldDescriptor getField(String name) {
103         return (FieldDescriptor) fields.get(name);       
104     }
105
106     public LabelDescriptor getLabel(String name) {
107         return (LabelDescriptor) labels.get(name);
108     }
109
110     public void addField(FieldDescriptor fd) {
111         if (getField(fd.getSymbol()) != null) {
112             throw new IRException("Can not overwrite a field once it has been added.");
113         }        
114         fields.put(fd.getSymbol(), fd);
115         fieldlist.addElement(fd);
116     }
117
118     public void addLabel(LabelDescriptor ld) {
119         if (getLabel(ld.getSymbol()) != null) {
120             throw new IRException("Can not overwrite a label once it has been added.");
121         }
122         labels.put(ld.getSymbol(), ld);
123     }
124
125     public TypeDescriptor getSubType() {
126         return subtype;
127     }
128
129     public void setSubType(TypeDescriptor td) {
130         subtype = td;
131     }
132
133     public boolean isSubtypeOf(TypeDescriptor td) {
134         if (td == this) {
135             return true;
136         } else {
137             return subtype.isSubtypeOf(td);
138         }
139     }
140
141 }