Adding functionality for printing sets.
[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                 basesize = new IntegerLiteralExpr(32);
53             } else {
54                 basesize = td.getSizeExpr();
55             }
56             Expr fieldsize;
57             if (fd instanceof ArrayDescriptor) {
58                 Expr totalsize = new OpExpr(Opcode.MULT, basesize, ((ArrayDescriptor) fd).getIndexBound());
59                 fieldsize=totalsize;
60             } else {
61                 fieldsize=basesize;
62             }
63             if (td instanceof ReservedTypeDescriptor) {
64                 ReservedTypeDescriptor rtd=(ReservedTypeDescriptor) td;
65                 if (rtd==ReservedTypeDescriptor.BIT) {
66                     aligned=false;
67                 } else {
68                     if (!aligned) {
69                         size=new OpExpr(Opcode.RND, size,null);
70                         aligned=true;
71                     }
72                 }
73             } else {
74                 if (!aligned) {
75                     size=new OpExpr(Opcode.RND, size,null);
76                     aligned=true;
77                 }
78             }
79
80             if (fd == field) { /* stop, reached target field */
81                 break;
82             }
83
84             size = new OpExpr(Opcode.ADD, fieldsize, size);
85         }
86
87         if ((field==null)&&(!aligned))
88             return new OpExpr(Opcode.RND, size, null);
89         return size;
90     }
91
92     public Iterator getFields() {
93         return fields.values().iterator();
94     }
95
96     public Iterator getLabels() {
97         return labels.values().iterator();
98     }
99
100     public FieldDescriptor getField(String name) {
101         return (FieldDescriptor) fields.get(name);       
102     }
103
104     public LabelDescriptor getLabel(String name) {
105         return (LabelDescriptor) labels.get(name);
106     }
107
108     public void addField(FieldDescriptor fd) {
109         if (getField(fd.getSymbol()) != null) {
110             throw new IRException("Can not overwrite a field once it has been added.");
111         }        
112         fields.put(fd.getSymbol(), fd);
113         fieldlist.addElement(fd);
114     }
115
116     public void addLabel(LabelDescriptor ld) {
117         if (getLabel(ld.getSymbol()) != null) {
118             throw new IRException("Can not overwrite a label once it has been added.");
119         }
120         labels.put(ld.getSymbol(), ld);
121     }
122
123     public TypeDescriptor getSuperType() {
124         return subtype;
125     }
126
127     public void setSuperType(TypeDescriptor td) {
128         subtype = td;
129     }
130
131     public boolean isSubtypeOf(TypeDescriptor td) {
132         if (td == this) {
133             return true;
134         } else {
135             if (subtype==null)
136                 return false;
137             return subtype.isSubtypeOf(td);
138         }
139     }
140
141     public void generate_printout(CodeWriter cr, VarDescriptor vd) {
142         // #TBD#: does not support printing out fields that have variable size, substructures, etc
143
144         cr.outputline("printf(\"" + getSymbol() + " %p: \", " + vd.getSafeSymbol() + ");");     
145         for (int i = 0; i < fieldlist.size(); i++) {
146             FieldDescriptor fd = (FieldDescriptor) fieldlist.elementAt(i);                                                      
147             cr.outputline("printf(\"\\n\\t" + fd.getSymbol() + " = \");");
148             if (fd.getPtr()) { 
149                 cr.outputline("printf(\"(" + fd.getType().getSymbol() + ") %p \", ((int *)" + vd.getSafeSymbol() + ")[" + i + "]);");
150             } else if ( fd.getType() instanceof ReservedTypeDescriptor) {
151                 cr.outputline("printf(\"%d \", ((int *)" + vd.getSafeSymbol() + ")[" + i + "]);");              
152             } else {
153                 cr.outputline("printf(\"unsupported, breaking\");");
154                 break;
155             }
156         }
157         
158         cr.outputline("printf(\"\\n\");");
159     }
160
161 }