Mercurial > projects > ddmd
annotate dmd/EqualExp.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | 60bb0fe4563e |
children | b0d41ff5e0df |
rev | line source |
---|---|
72 | 1 module dmd.EqualExp; |
2 | |
114 | 3 import dmd.common; |
79 | 4 import dmd.ErrorExp; |
72 | 5 import dmd.Expression; |
0 | 6 import dmd.Id; |
72 | 7 import dmd.Identifier; |
8 import dmd.InterState; | |
9 import dmd.Loc; | |
10 import dmd.Scope; | |
11 import dmd.IRState; | |
12 import dmd.BinExp; | |
0 | 13 import dmd.TOK; |
14 import dmd.Type; | |
15 import dmd.AddrExp; | |
16 import dmd.VarExp; | |
17 import dmd.IntegerExp; | |
18 import dmd.TY; | |
19 import dmd.Token; | |
20 import dmd.NotExp; | |
21 import dmd.WANT; | |
72 | 22 import dmd.GlobalExpressions; |
23 | |
0 | 24 import dmd.backend.elem; |
25 import dmd.backend.OPER; | |
26 import dmd.backend.Util; | |
27 import dmd.backend.TYM; | |
28 import dmd.backend.RTLSYM; | |
29 | |
30 import dmd.codegen.Util; | |
31 | |
32 import dmd.expression.util.arrayTypeCompatible; | |
33 import dmd.expression.Util; | |
72 | 34 import dmd.expression.Equal; |
35 | |
0 | 36 class EqualExp : BinExp |
37 { | |
38 this(TOK op, Loc loc, Expression e1, Expression e2) | |
39 { | |
178 | 40 register(); |
0 | 41 super(loc, op, EqualExp.sizeof, e1, e2); |
42 assert(op == TOK.TOKequal || op == TOK.TOKnotequal); | |
43 } | |
44 | |
72 | 45 override Expression semantic(Scope sc) |
0 | 46 { |
47 Expression e; | |
48 | |
49 //printf("EqualExp.semantic('%s')\n", toChars()); | |
50 if (type) | |
51 return this; | |
52 | |
53 BinExp.semanticp(sc); | |
54 | |
55 /* Before checking for operator overloading, check to see if we're | |
56 * comparing the addresses of two statics. If so, we can just see | |
57 * if they are the same symbol. | |
58 */ | |
59 if (e1.op == TOK.TOKaddress && e2.op == TOK.TOKaddress) | |
60 { | |
61 AddrExp ae1 = cast(AddrExp)e1; | |
62 AddrExp ae2 = cast(AddrExp)e2; | |
63 | |
64 if (ae1.e1.op == TOK.TOKvar && ae2.e1.op == TOK.TOKvar) | |
65 { | |
66 VarExp ve1 = cast(VarExp)ae1.e1; | |
67 VarExp ve2 = cast(VarExp)ae2.e1; | |
68 | |
69 if (ve1.var == ve2.var /*|| ve1.var.toSymbol() == ve2.var.toSymbol()*/) | |
70 { | |
71 // They are the same, result is 'true' for ==, 'false' for != | |
72 e = new IntegerExp(loc, (op == TOK.TOKequal), Type.tboolean); | |
73 return e; | |
74 } | |
75 } | |
76 } | |
77 | |
79 | 78 Type t1 = e1.type.toBasetype(); |
79 Type t2 = e2.type.toBasetype(); | |
80 if (t1.ty == TY.Tclass && e2.op == TOK.TOKnull || t2.ty == TY.Tclass && e1.op == TOK.TOKnull) | |
0 | 81 { |
82 error("use '%s' instead of '%s' when comparing with null", | |
83 Token.toChars(op == TOK.TOKequal ? TOK.TOKidentity : TOK.TOKnotidentity), | |
84 Token.toChars(op)); | |
85 } | |
86 | |
87 //if (e2.op != TOKnull) | |
88 { | |
89 e = op_overload(sc); | |
90 if (e) | |
91 { | |
92 if (op == TOK.TOKnotequal) | |
93 { | |
94 e = new NotExp(e.loc, e); | |
95 e = e.semantic(sc); | |
96 } | |
97 | |
98 return e; | |
99 } | |
100 } | |
101 | |
79 | 102 // Disallow comparing T[]==T and T==T[] |
103 if (e1.op == TOKslice && t1.ty == Tarray && e2.implicitConvTo(t1.nextOf()) || | |
104 e2.op == TOKslice && t2.ty == Tarray && e1.implicitConvTo(t2.nextOf())) | |
105 { | |
106 incompatibleTypes(); | |
107 return new ErrorExp(); | |
108 } | |
109 | |
0 | 110 e = typeCombine(sc); |
111 type = Type.tboolean; | |
112 | |
113 // Special handling for array comparisons | |
114 if (!arrayTypeCompatible(loc, e1.type, e2.type)) | |
115 { | |
116 if (e1.type != e2.type && e1.type.isfloating() && e2.type.isfloating()) | |
117 { | |
118 // Cast both to complex | |
119 e1 = e1.castTo(sc, Type.tcomplex80); | |
120 e2 = e2.castTo(sc, Type.tcomplex80); | |
121 } | |
122 } | |
123 | |
124 return e; | |
125 } | |
126 | |
72 | 127 override Expression optimize(int result) |
0 | 128 { |
129 Expression e; | |
130 | |
131 //printf("EqualExp::optimize(result = %x) %s\n", result, toChars()); | |
132 e1 = e1.optimize(WANTvalue | (result & WANTinterpret)); | |
133 e2 = e2.optimize(WANTvalue | (result & WANTinterpret)); | |
134 e = this; | |
135 | |
136 Expression e1 = fromConstInitializer(result, this.e1); | |
137 Expression e2 = fromConstInitializer(result, this.e2); | |
138 | |
139 e = Equal(op, type, e1, e2); | |
140 if (e is EXP_CANT_INTERPRET) | |
141 e = this; | |
142 return e; | |
143 } | |
144 | |
72 | 145 override Expression interpret(InterState istate) |
0 | 146 { |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
147 return interpretCommon2(istate, &Equal); |
0 | 148 } |
149 | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
150 override bool isBit() |
0 | 151 { |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
152 return true; |
0 | 153 } |
154 | |
72 | 155 override bool isCommutative() |
0 | 156 { |
157 return true; | |
158 } | |
159 | |
72 | 160 override Identifier opId() |
0 | 161 { |
162 return Id.eq; | |
163 } | |
164 | |
72 | 165 override elem* toElem(IRState* irs) |
0 | 166 { |
167 //printf("EqualExp::toElem() %s\n", toChars()); | |
168 elem* e; | |
169 OPER eop; | |
170 Type t1 = e1.type.toBasetype(); | |
171 Type t2 = e2.type.toBasetype(); | |
172 | |
173 switch (op) | |
174 { | |
175 case TOKequal: eop = OPeqeq; break; | |
176 case TOKnotequal: eop = OPne; break; | |
177 default: | |
178 dump(0); | |
179 assert(0); | |
180 } | |
181 | |
182 //printf("EqualExp::toElem()\n"); | |
183 if (t1.ty == Tstruct) | |
184 { // Do bit compare of struct's | |
185 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
115
diff
changeset
|
186 auto es1 = e1.toElem(irs); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
115
diff
changeset
|
187 auto es2 = e2.toElem(irs); |
0 | 188 es1 = addressElem(es1, t1); |
189 es2 = addressElem(es2, t2); | |
190 e = el_param(es1, es2); | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
115
diff
changeset
|
191 auto ecount = el_long(TYint, t1.size()); |
0 | 192 e = el_bin(OPmemcmp, TYint, e, ecount); |
193 e = el_bin(eop, TYint, e, el_long(TYint, 0)); | |
194 el_setLoc(e,loc); | |
195 } | |
196 /// static if (false) { | |
197 /// else if (t1.ty == Tclass && t2.ty == Tclass) | |
198 /// { | |
199 /// elem *ec1; | |
200 /// elem *ec2; | |
201 /// | |
202 /// ec1 = e1.toElem(irs); | |
203 /// ec2 = e2.toElem(irs); | |
204 /// e = el_bin(OPcall,TYint,el_var(rtlsym[RTLSYM_OBJ_EQ]),el_param(ec1, ec2)); | |
205 /// } | |
206 /// } | |
207 else if ((t1.ty == Tarray || t1.ty == Tsarray) && | |
208 (t2.ty == Tarray || t2.ty == Tsarray)) | |
209 { | |
210 Type telement = t1.nextOf().toBasetype(); | |
211 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
115
diff
changeset
|
212 auto ea1 = e1.toElem(irs); |
0 | 213 ea1 = array_toDarray(t1, ea1); |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
115
diff
changeset
|
214 auto ea2 = e2.toElem(irs); |
0 | 215 ea2 = array_toDarray(t2, ea2); |
216 | |
217 version (DMDV2) { | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
115
diff
changeset
|
218 auto ep = el_params(telement.arrayOf().getInternalTypeInfo(null).toElem(irs), |
0 | 219 ea2, ea1, null); |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
115
diff
changeset
|
220 int rtlfunc = RTLSYM_ARRAYEQ2; |
0 | 221 } else { |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
115
diff
changeset
|
222 auto ep = el_params(telement.getInternalTypeInfo(null).toElem(irs), ea2, ea1, null); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
115
diff
changeset
|
223 int rtlfunc = RTLSYM_ARRAYEQ; |
0 | 224 } |
225 e = el_bin(OPcall, TYint, el_var(rtlsym[rtlfunc]), ep); | |
226 if (op == TOKnotequal) | |
227 e = el_bin(OPxor, TYint, e, el_long(TYint, 1)); | |
228 el_setLoc(e,loc); | |
229 } | |
230 else | |
231 e = toElemBin(irs, eop); | |
232 | |
233 return e; | |
234 } | |
235 } | |
236 |