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