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