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