correct
[repair.git] / Repair / RepairCompiler / MCC / IR / VarExpr.java
1 package MCC.IR;
2
3 import java.util.*;
4
5 public class VarExpr extends Expr {
6     static boolean DOMEMCHECKS=false;
7     static boolean DOTYPECHECKS=false;
8     static boolean DONULL=false;
9
10     String varname;
11     VarDescriptor vd = null;
12     boolean typechecked = false;
13
14     public Set freeVars() {
15         HashSet hs=new HashSet();
16         hs.add(vd);
17         return hs;
18     }
19
20     public Expr getLower() {
21         return vd.getLower();
22     }
23
24     public Expr getUpper() {
25         return vd.getUpper();
26     }
27
28     public SetDescriptor getSet() {
29         if (vd==null)
30             return null;
31         return vd.getSet();
32     }
33
34     public VarExpr(String varname) {
35         this.varname = varname;
36     }
37
38     public VarExpr(VarDescriptor vd) {
39         this.vd=vd;
40         varname=vd.getSymbol();
41         this.td = vd.getType();
42     }
43
44     public String name() {
45         return varname;
46     }
47
48     public boolean usesDescriptor(Descriptor d) {
49         if (d==vd)
50             return true;
51         return false;
52     }
53
54     public Set useDescriptor(Descriptor d) {
55         HashSet newset=new HashSet();
56         if (d==vd)
57             newset.add(this);
58         return newset;
59     }
60
61     public boolean isNonNull() {
62         return true;
63     }
64
65     public boolean equals(Map remap, Expr e) {
66         if (e==null||!(e instanceof VarExpr))
67             return false;
68         VarExpr ve=(VarExpr)e;
69         if (vd==null)
70             throw new Error("Uninitialized VarDescriptor");
71         if (ve.vd==null)
72             throw new Error("e has uninitialized VarDescriptor");
73         VarDescriptor nvd=vd;
74         if (remap!=null&&remap.containsKey(nvd))
75             nvd=(VarDescriptor)remap.get(nvd);
76         if (nvd!=ve.vd)
77             return false;
78         return true;
79     }
80
81     public Set getInversedRelations() {
82         return new HashSet();
83     }
84
85     public Set getRequiredDescriptors() {
86         Set s=new HashSet();
87         s.add(vd);
88         return s;
89
90     }
91
92     public VarDescriptor getVar() {
93         return vd;
94     }
95
96     public boolean isValue() {
97         return vd.isGlobal();
98     }
99
100     public boolean isInvariant(Set vars) {
101         return vd.isGlobal()||vars.contains(vd);
102     }
103
104     public Set findInvariants(Set vars) {
105         if (isInvariant(vars)) {
106             Set s=new HashSet();
107             s.add(this);
108             return s;
109         } else
110             return new HashSet();
111     }
112
113     public void generate(CodeWriter writer, VarDescriptor dest) {
114         // #TBD#: bit of a hack, really should have been type checked properly
115         assert vd != null;
116         assert vd.getType() != null;
117         this.td = vd.getType();
118
119         if (writer.getInvariantValue()!=null&&
120             writer.getInvariantValue().isInvariant(this)) {
121             writer.addDeclaration(vd.getType().getGenerateType().getSafeSymbol(),dest.getSafeSymbol());
122             writer.outputline(dest.getSafeSymbol()+"="+writer.getInvariantValue().getValue(this).getSafeSymbol()+";");
123             writer.outputline("maybe="+writer.getInvariantValue().getMaybe(this).getSafeSymbol()+";");
124             return;
125         }
126
127         writer.addDeclaration(vd.getType().getGenerateType().getSafeSymbol(),dest.getSafeSymbol());
128         writer.outputline(dest.getSafeSymbol() +
129                           " = (" + vd.getType().getGenerateType().getSafeSymbol() + ") " + vd.getSafeSymbol() + "; /*varexpr*/");
130         if (vd.isGlobal() && (DOTYPECHECKS||DOMEMCHECKS) && (td instanceof StructureTypeDescriptor)) {
131             VarDescriptor typevar=VarDescriptor.makeNew("typechecks");
132             writer.outputline("if ("+dest.getSafeSymbol()+")");
133             writer.startblock();
134             if (DOTYPECHECKS) {
135                 writer.addDeclaration("bool",typevar.getSafeSymbol());
136                 writer.outputline(typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
137             } else {
138                 writer.addDeclaration("bool",typevar.getSafeSymbol());
139                 writer.outputline(typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
140             }
141             writer.outputline("if (!"+typevar.getSafeSymbol()+")");
142             writer.startblock();
143             writer.outputline(dest.getSafeSymbol()+"=0;");
144             if (DONULL)
145                 writer.outputline(vd.getSafeSymbol()+"=0;");
146             writer.endblock();
147             writer.endblock();
148         }
149     }
150
151     public void prettyPrint(PrettyPrinter pp) {
152         pp.output(varname);
153     }
154
155     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
156         typechecked = true;
157         vd = (VarDescriptor) sa.getSymbolTable().get(varname);
158         if (vd == null) {
159             //System.out.println(varname);
160             sa.getErrorReporter().report(null, "Undefined variable '" + varname + "'");
161             return null;
162         }
163         assert vd.getType() != null;
164         this.td = vd.getType();
165         return this.td;
166     }
167 }