mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-03-12 23:21:50 +01:00
First merge of 2.064 beta.
This corresponds to DMD commit a913ce4bc59a94a022a27e390fc841f4aededffb. Doesn't build Phobos yet.
This commit is contained in:
committed by
Kai Nacke
parent
c400d180d2
commit
cb341586e3
237
dmd2/optimize.c
237
dmd2/optimize.c
@@ -25,13 +25,6 @@
|
||||
#include "init.h"
|
||||
#include "enum.h"
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "d-gcc-real.h"
|
||||
#endif
|
||||
|
||||
static real_t zero; // work around DMC bug for now
|
||||
|
||||
|
||||
/*************************************
|
||||
* If variable has a const initializer,
|
||||
* return that initializer.
|
||||
@@ -51,12 +44,10 @@ Expression *expandVar(int result, VarDeclaration *v)
|
||||
{
|
||||
if (!v->type)
|
||||
{
|
||||
//error("ICE");
|
||||
return e;
|
||||
}
|
||||
Type *tb = v->type->toBasetype();
|
||||
if (result & WANTinterpret ||
|
||||
v->storage_class & STCmanifest ||
|
||||
if ( v->storage_class & STCmanifest ||
|
||||
v->type->toBasetype()->isscalar() ||
|
||||
((result & WANTexpand) && (tb->ty != Tsarray && tb->ty != Tstruct))
|
||||
)
|
||||
@@ -65,25 +56,25 @@ Expression *expandVar(int result, VarDeclaration *v)
|
||||
{
|
||||
if (v->inuse)
|
||||
{ if (v->storage_class & STCmanifest)
|
||||
{
|
||||
v->error("recursive initialization of constant");
|
||||
goto Lerror;
|
||||
}
|
||||
goto L1;
|
||||
}
|
||||
Expression *ei = v->getConstInitializer();
|
||||
if (!ei)
|
||||
{ if (v->storage_class & STCmanifest)
|
||||
{
|
||||
v->error("enum cannot be initialized with %s", v->init->toChars());
|
||||
goto Lerror;
|
||||
}
|
||||
goto L1;
|
||||
}
|
||||
if (ei->op == TOKconstruct || ei->op == TOKblit)
|
||||
{ AssignExp *ae = (AssignExp *)ei;
|
||||
ei = ae->e2;
|
||||
if (result & WANTinterpret)
|
||||
{
|
||||
v->inuse++;
|
||||
ei = ei->optimize(result);
|
||||
v->inuse--;
|
||||
}
|
||||
else if (ei->isConst() != 1 && ei->op != TOKstring)
|
||||
if (ei->isConst() != 1 && ei->op != TOKstring)
|
||||
goto L1;
|
||||
|
||||
if (ei->type == v->type)
|
||||
@@ -97,8 +88,7 @@ Expression *expandVar(int result, VarDeclaration *v)
|
||||
else
|
||||
goto L1;
|
||||
}
|
||||
else if (!(result & WANTinterpret) &&
|
||||
!(v->storage_class & STCmanifest) &&
|
||||
else if (!(v->storage_class & STCmanifest) &&
|
||||
ei->isConst() != 1 && ei->op != TOKstring &&
|
||||
ei->op != TOKaddress)
|
||||
{
|
||||
@@ -135,6 +125,9 @@ Expression *expandVar(int result, VarDeclaration *v)
|
||||
L1:
|
||||
//if (e) printf("\te = %p, %s, e->type = %d, %s\n", e, e->toChars(), e->type->ty, e->type->toChars());
|
||||
return e;
|
||||
|
||||
Lerror:
|
||||
return new ErrorExp();
|
||||
}
|
||||
|
||||
|
||||
@@ -166,16 +159,6 @@ Expression *fromConstInitializer(int result, Expression *e1)
|
||||
else
|
||||
{
|
||||
e = e1;
|
||||
/* If we needed to interpret, generate an error.
|
||||
* Don't give an error if it's a template parameter
|
||||
*/
|
||||
if (v && (result & WANTinterpret) &&
|
||||
!(v->storage_class & STCtemplateparameter))
|
||||
{
|
||||
e1->error("variable %s cannot be read at compile time", v->toChars());
|
||||
e = e->copy();
|
||||
e->type = Type::terror;
|
||||
}
|
||||
}
|
||||
}
|
||||
return e;
|
||||
@@ -202,11 +185,11 @@ Expression *VarExp::optimize(int result, bool keepLvalue)
|
||||
Expression *TupleExp::optimize(int result, bool keepLvalue)
|
||||
{
|
||||
if (e0)
|
||||
e0 = e0->optimize(WANTvalue | (result & WANTinterpret));
|
||||
e0 = e0->optimize(WANTvalue);
|
||||
for (size_t i = 0; i < exps->dim; i++)
|
||||
{
|
||||
Expression *e = (*exps)[i];
|
||||
e = e->optimize(WANTvalue | (result & WANTinterpret));
|
||||
e = e->optimize(WANTvalue);
|
||||
(*exps)[i] = e;
|
||||
}
|
||||
return this;
|
||||
@@ -219,7 +202,7 @@ Expression *ArrayLiteralExp::optimize(int result, bool keepLvalue)
|
||||
for (size_t i = 0; i < elements->dim; i++)
|
||||
{ Expression *e = (*elements)[i];
|
||||
|
||||
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
|
||||
e = e->optimize(WANTvalue | (result & WANTexpand));
|
||||
(*elements)[i] = e;
|
||||
}
|
||||
}
|
||||
@@ -232,11 +215,11 @@ Expression *AssocArrayLiteralExp::optimize(int result, bool keepLvalue)
|
||||
for (size_t i = 0; i < keys->dim; i++)
|
||||
{ Expression *e = (*keys)[i];
|
||||
|
||||
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
|
||||
e = e->optimize(WANTvalue | (result & WANTexpand));
|
||||
(*keys)[i] = e;
|
||||
|
||||
e = (*values)[i];
|
||||
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
|
||||
e = e->optimize(WANTvalue | (result & WANTexpand));
|
||||
(*values)[i] = e;
|
||||
}
|
||||
return this;
|
||||
@@ -253,7 +236,7 @@ Expression *StructLiteralExp::optimize(int result, bool keepLvalue)
|
||||
{ Expression *e = (*elements)[i];
|
||||
if (!e)
|
||||
continue;
|
||||
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
|
||||
e = e->optimize(WANTvalue | (result & WANTexpand));
|
||||
(*elements)[i] = e;
|
||||
}
|
||||
}
|
||||
@@ -328,8 +311,6 @@ Expression *BoolExp::optimize(int result, bool keepLvalue)
|
||||
Expression *SymOffExp::optimize(int result, bool keepLvalue)
|
||||
{
|
||||
assert(var);
|
||||
if ((result & WANTinterpret) && var->isThreadlocal())
|
||||
error("cannot take address of thread-local variable %s at compile time", var->toChars());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -382,7 +363,7 @@ Expression *AddrExp::optimize(int result, bool keepLvalue)
|
||||
|
||||
if (ae->e2->op == TOKint64 && ae->e1->op == TOKvar)
|
||||
{
|
||||
dinteger_t index = ae->e2->toInteger();
|
||||
sinteger_t index = ae->e2->toInteger();
|
||||
VarExp *ve = (VarExp *)ae->e1;
|
||||
if (ve->type->ty == Tsarray
|
||||
&& !ve->var->isImportedSymbol())
|
||||
@@ -390,7 +371,10 @@ Expression *AddrExp::optimize(int result, bool keepLvalue)
|
||||
TypeSArray *ts = (TypeSArray *)ve->type;
|
||||
sinteger_t dim = ts->dim->toInteger();
|
||||
if (index < 0 || index >= dim)
|
||||
{
|
||||
error("array index %lld is out of bounds [0..%lld]", index, dim);
|
||||
return new ErrorExp();
|
||||
}
|
||||
e = new SymOffExp(loc, ve->var, index * ts->nextOf()->size());
|
||||
e->type = type;
|
||||
return e;
|
||||
@@ -499,16 +483,6 @@ Expression *NewExp::optimize(int result, bool keepLvalue)
|
||||
(*arguments)[i] = e;
|
||||
}
|
||||
}
|
||||
if (result & WANTinterpret)
|
||||
{
|
||||
Expression *eresult = interpret(NULL);
|
||||
if (eresult == EXP_CANT_INTERPRET)
|
||||
return this;
|
||||
if (eresult && eresult != EXP_VOID_INTERPRET)
|
||||
return eresult;
|
||||
else
|
||||
error("cannot evaluate %s at compile time", toChars());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -540,49 +514,19 @@ Expression *CallExp::optimize(int result, bool keepLvalue)
|
||||
return this;
|
||||
|
||||
#if 1
|
||||
if (result & WANTinterpret)
|
||||
{
|
||||
Expression *eresult = interpret(NULL);
|
||||
if (eresult == EXP_CANT_INTERPRET)
|
||||
return e;
|
||||
if (eresult && eresult != EXP_VOID_INTERPRET)
|
||||
e = eresult;
|
||||
else
|
||||
error("cannot evaluate %s at compile time", toChars());
|
||||
}
|
||||
#else
|
||||
if (e1->op == TOKvar)
|
||||
{
|
||||
FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration();
|
||||
if (fd)
|
||||
{
|
||||
enum BUILTIN b = fd->isBuiltin();
|
||||
BUILTIN b = fd->isBuiltin();
|
||||
if (b)
|
||||
{
|
||||
e = eval_builtin(b, arguments);
|
||||
if (!e) // failed
|
||||
e = this; // evaluate at runtime
|
||||
}
|
||||
else if (result & WANTinterpret)
|
||||
{
|
||||
Expression *eresult = fd->interpret(NULL, arguments);
|
||||
if (eresult && eresult != EXP_VOID_INTERPRET)
|
||||
e = eresult;
|
||||
else
|
||||
error("cannot evaluate %s at compile time", toChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (e1->op == TOKdotvar && result & WANTinterpret)
|
||||
{ DotVarExp *dve = (DotVarExp *)e1;
|
||||
FuncDeclaration *fd = dve->var->isFuncDeclaration();
|
||||
if (fd)
|
||||
{
|
||||
Expression *eresult = fd->interpret(NULL, arguments, dve->e1);
|
||||
if (eresult && eresult != EXP_VOID_INTERPRET)
|
||||
e = eresult;
|
||||
else
|
||||
error("cannot evaluate %s at compile time", toChars());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -598,7 +542,7 @@ Expression *CastExp::optimize(int result, bool keepLvalue)
|
||||
//printf("e1->type %s\n", e1->type->toChars());
|
||||
//printf("type = %p\n", type);
|
||||
assert(type);
|
||||
enum TOK op1 = e1->op;
|
||||
TOK op1 = e1->op;
|
||||
#define X 0
|
||||
|
||||
Expression *e1old = e1;
|
||||
@@ -709,7 +653,7 @@ Expression *BinExp::optimize(int result, bool keepLvalue)
|
||||
d_uns64 sz = e1->type->size() * 8;
|
||||
if (i2 < 0 || i2 >= sz)
|
||||
{ error("shift assign by %lld is outside the range 0..%llu", i2, (ulonglong)sz - 1);
|
||||
e2 = new IntegerExp(0);
|
||||
return new ErrorExp();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -722,6 +666,10 @@ Expression *AddExp::optimize(int result, bool keepLvalue)
|
||||
//printf("AddExp::optimize(%s)\n", toChars());
|
||||
e1 = e1->optimize(result);
|
||||
e2 = e2->optimize(result);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
if (e1->isConst() && e2->isConst())
|
||||
{
|
||||
if (e1->op == TOKsymoff && e2->op == TOKsymoff)
|
||||
@@ -738,6 +686,10 @@ Expression *MinExp::optimize(int result, bool keepLvalue)
|
||||
|
||||
e1 = e1->optimize(result);
|
||||
e2 = e2->optimize(result);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
if (e1->isConst() && e2->isConst())
|
||||
{
|
||||
if (e2->op == TOKsymoff)
|
||||
@@ -755,6 +707,10 @@ Expression *MulExp::optimize(int result, bool keepLvalue)
|
||||
//printf("MulExp::optimize(result = %d) %s\n", result, toChars());
|
||||
e1 = e1->optimize(result);
|
||||
e2 = e2->optimize(result);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
if (e1->isConst() == 1 && e2->isConst() == 1)
|
||||
{
|
||||
e = Mul(type, e1, e2);
|
||||
@@ -770,6 +726,10 @@ Expression *DivExp::optimize(int result, bool keepLvalue)
|
||||
//printf("DivExp::optimize(%s)\n", toChars());
|
||||
e1 = e1->optimize(result);
|
||||
e2 = e2->optimize(result);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
if (e1->isConst() == 1 && e2->isConst() == 1)
|
||||
{
|
||||
e = Div(type, e1, e2);
|
||||
@@ -784,6 +744,10 @@ Expression *ModExp::optimize(int result, bool keepLvalue)
|
||||
|
||||
e1 = e1->optimize(result);
|
||||
e2 = e2->optimize(result);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
if (e1->isConst() == 1 && e2->isConst() == 1)
|
||||
{
|
||||
e = Mod(type, e1, e2);
|
||||
@@ -798,13 +762,17 @@ Expression *shift_optimize(int result, BinExp *e, Expression *(*shift)(Type *, E
|
||||
|
||||
e->e1 = e->e1->optimize(result);
|
||||
e->e2 = e->e2->optimize(result);
|
||||
if (e->e1->op == TOKerror)
|
||||
return e->e1;
|
||||
if (e->e2->op == TOKerror)
|
||||
return e->e2;
|
||||
if (e->e2->isConst() == 1)
|
||||
{
|
||||
sinteger_t i2 = e->e2->toInteger();
|
||||
d_uns64 sz = e->e1->type->size() * 8;
|
||||
if (i2 < 0 || i2 >= sz)
|
||||
{ e->error("shift by %lld is outside the range 0..%llu", i2, (ulonglong)sz - 1);
|
||||
e->e2 = new IntegerExp(0);
|
||||
return new ErrorExp();
|
||||
}
|
||||
if (e->e1->isConst() == 1)
|
||||
ex = (*shift)(e->type, e->e1, e->e2);
|
||||
@@ -835,6 +803,10 @@ Expression *AndExp::optimize(int result, bool keepLvalue)
|
||||
|
||||
e1 = e1->optimize(result);
|
||||
e2 = e2->optimize(result);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
if (e1->isConst() == 1 && e2->isConst() == 1)
|
||||
e = And(type, e1, e2);
|
||||
else
|
||||
@@ -847,6 +819,10 @@ Expression *OrExp::optimize(int result, bool keepLvalue)
|
||||
|
||||
e1 = e1->optimize(result);
|
||||
e2 = e2->optimize(result);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
if (e1->isConst() == 1 && e2->isConst() == 1)
|
||||
e = Or(type, e1, e2);
|
||||
else
|
||||
@@ -859,6 +835,10 @@ Expression *XorExp::optimize(int result, bool keepLvalue)
|
||||
|
||||
e1 = e1->optimize(result);
|
||||
e2 = e2->optimize(result);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
if (e1->isConst() == 1 && e2->isConst() == 1)
|
||||
e = Xor(type, e1, e2);
|
||||
else
|
||||
@@ -871,6 +851,10 @@ Expression *PowExp::optimize(int result, bool keepLvalue)
|
||||
|
||||
e1 = e1->optimize(result);
|
||||
e2 = e2->optimize(result);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
|
||||
// Replace 1 ^^ x or 1.0^^x by (x, 1)
|
||||
if ((e1->op == TOKint64 && e1->toInteger() == 1) ||
|
||||
@@ -928,6 +912,21 @@ Expression *PowExp::optimize(int result, bool keepLvalue)
|
||||
}
|
||||
e = this;
|
||||
}
|
||||
|
||||
if (e1->op == TOKint64 && e1->toInteger() > 0 &&
|
||||
!((e1->toInteger() - 1) & e1->toInteger()) && // is power of two
|
||||
e2->type->isintegral() && e2->type->isunsigned())
|
||||
{
|
||||
dinteger_t i = e1->toInteger();
|
||||
dinteger_t mul = 1;
|
||||
while ((i >>= 1) > 1)
|
||||
mul++;
|
||||
Expression *shift = new MulExp(loc, e2, new IntegerExp(loc, mul, e2->type));
|
||||
shift->type = Type::tshiftcnt;
|
||||
e = new ShlExp(loc, new IntegerExp(loc, 1, e1->type), shift);
|
||||
e->type = type;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -941,15 +940,10 @@ Expression *CommaExp::optimize(int result, bool keepLvalue)
|
||||
// In particular, if the comma returns a temporary variable, it needs
|
||||
// to be an lvalue (this is particularly important for struct constructors)
|
||||
|
||||
if (result & WANTinterpret)
|
||||
{ // Interpreting comma needs special treatment, because it may
|
||||
// contain compiler-generated declarations.
|
||||
e = interpret(NULL);
|
||||
return (e == EXP_CANT_INTERPRET) ? this : e;
|
||||
}
|
||||
|
||||
e1 = e1->optimize(result & WANTinterpret);
|
||||
e1 = e1->optimize(0);
|
||||
e2 = e2->optimize(result, keepLvalue);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (!e1 || e1->op == TOKint64 || e1->op == TOKfloat64 || !e1->hasSideEffect())
|
||||
{
|
||||
e = e2;
|
||||
@@ -966,9 +960,12 @@ Expression *ArrayLengthExp::optimize(int result, bool keepLvalue)
|
||||
{ Expression *e;
|
||||
|
||||
//printf("ArrayLengthExp::optimize(result = %d) %s\n", result, toChars());
|
||||
e1 = e1->optimize(WANTvalue | WANTexpand | (result & WANTinterpret));
|
||||
e1 = e1->optimize(WANTvalue | WANTexpand);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
e = this;
|
||||
if (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKassocarrayliteral)
|
||||
if (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKassocarrayliteral ||
|
||||
e1->type->toBasetype()->ty == Tsarray)
|
||||
{
|
||||
e = ArrayLength(type, e1);
|
||||
}
|
||||
@@ -978,11 +975,15 @@ Expression *ArrayLengthExp::optimize(int result, bool keepLvalue)
|
||||
Expression *EqualExp::optimize(int result, bool keepLvalue)
|
||||
{
|
||||
//printf("EqualExp::optimize(result = %x) %s\n", result, toChars());
|
||||
e1 = e1->optimize(WANTvalue | (result & WANTinterpret));
|
||||
e2 = e2->optimize(WANTvalue | (result & WANTinterpret));
|
||||
e1 = e1->optimize(WANTvalue);
|
||||
e2 = e2->optimize(WANTvalue);
|
||||
|
||||
Expression *e1 = fromConstInitializer(result, this->e1);
|
||||
Expression *e2 = fromConstInitializer(result, this->e2);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
|
||||
Expression *e = Equal(op, type, e1, e2);
|
||||
if (e == EXP_CANT_INTERPRET)
|
||||
@@ -993,13 +994,19 @@ Expression *EqualExp::optimize(int result, bool keepLvalue)
|
||||
Expression *IdentityExp::optimize(int result, bool keepLvalue)
|
||||
{
|
||||
//printf("IdentityExp::optimize(result = %d) %s\n", result, toChars());
|
||||
e1 = e1->optimize(WANTvalue | (result & WANTinterpret));
|
||||
e2 = e2->optimize(WANTvalue | (result & WANTinterpret));
|
||||
e1 = e1->optimize(WANTvalue);
|
||||
e2 = e2->optimize(WANTvalue);
|
||||
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
if (e2->op == TOKerror)
|
||||
return e2;
|
||||
|
||||
Expression *e = this;
|
||||
|
||||
if ((this->e1->isConst() && this->e2->isConst()) ||
|
||||
(this->e1->op == TOKnull && this->e2->op == TOKnull) ||
|
||||
(result & WANTinterpret))
|
||||
(this->e1->op == TOKnull && this->e2->op == TOKnull)
|
||||
)
|
||||
{
|
||||
e = Identity(op, type, this->e1, this->e2);
|
||||
if (e == EXP_CANT_INTERPRET)
|
||||
@@ -1042,13 +1049,13 @@ Expression *IndexExp::optimize(int result, bool keepLvalue)
|
||||
{ Expression *e;
|
||||
|
||||
//printf("IndexExp::optimize(result = %d) %s\n", result, toChars());
|
||||
e1 = e1->optimize(WANTvalue | (result & (WANTinterpret| WANTexpand)));
|
||||
e1 = e1->optimize(WANTvalue | (result & WANTexpand));
|
||||
|
||||
Expression *ex = fromConstInitializer(result, e1);
|
||||
|
||||
// We might know $ now
|
||||
setLengthVarIfKnown(lengthVar, ex);
|
||||
e2 = e2->optimize(WANTvalue | (result & WANTinterpret));
|
||||
e2 = e2->optimize(WANTvalue);
|
||||
if (keepLvalue)
|
||||
return this;
|
||||
e = Index(type, ex, e2);
|
||||
@@ -1063,7 +1070,7 @@ Expression *SliceExp::optimize(int result, bool keepLvalue)
|
||||
|
||||
//printf("SliceExp::optimize(result = %d) %s\n", result, toChars());
|
||||
e = this;
|
||||
e1 = e1->optimize(WANTvalue | (result & (WANTinterpret|WANTexpand)));
|
||||
e1 = e1->optimize(WANTvalue | (result & WANTexpand));
|
||||
if (!lwr)
|
||||
{ if (e1->op == TOKstring)
|
||||
{ // Convert slice of string literal into dynamic array
|
||||
@@ -1076,8 +1083,8 @@ Expression *SliceExp::optimize(int result, bool keepLvalue)
|
||||
e1 = fromConstInitializer(result, e1);
|
||||
// We might know $ now
|
||||
setLengthVarIfKnown(lengthVar, e1);
|
||||
lwr = lwr->optimize(WANTvalue | (result & WANTinterpret));
|
||||
upr = upr->optimize(WANTvalue | (result & WANTinterpret));
|
||||
lwr = lwr->optimize(WANTvalue);
|
||||
upr = upr->optimize(WANTvalue);
|
||||
e = Slice(type, e1, lwr, upr);
|
||||
if (e == EXP_CANT_INTERPRET)
|
||||
e = this;
|
||||
@@ -1089,7 +1096,9 @@ Expression *AndAndExp::optimize(int result, bool keepLvalue)
|
||||
{ Expression *e;
|
||||
|
||||
//printf("AndAndExp::optimize(%d) %s\n", result, toChars());
|
||||
e1 = e1->optimize(WANTflags | (result & WANTinterpret));
|
||||
e1 = e1->optimize(WANTflags);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
e = this;
|
||||
if (e1->isBool(FALSE))
|
||||
{
|
||||
@@ -1103,9 +1112,12 @@ Expression *AndAndExp::optimize(int result, bool keepLvalue)
|
||||
}
|
||||
else
|
||||
{
|
||||
e2 = e2->optimize(WANTflags | (result & WANTinterpret));
|
||||
e2 = e2->optimize(WANTflags);
|
||||
if (result && e2->type->toBasetype()->ty == Tvoid && !global.errors)
|
||||
{
|
||||
error("void has no value");
|
||||
return new ErrorExp();
|
||||
}
|
||||
if (e1->isConst())
|
||||
{
|
||||
if (e2->isConst())
|
||||
@@ -1128,7 +1140,9 @@ Expression *AndAndExp::optimize(int result, bool keepLvalue)
|
||||
Expression *OrOrExp::optimize(int result, bool keepLvalue)
|
||||
{ Expression *e;
|
||||
|
||||
e1 = e1->optimize(WANTflags | (result & WANTinterpret));
|
||||
e1 = e1->optimize(WANTflags);
|
||||
if (e1->op == TOKerror)
|
||||
return e1;
|
||||
e = this;
|
||||
if (e1->isBool(TRUE))
|
||||
{ // Replace with (e1, 1)
|
||||
@@ -1138,9 +1152,12 @@ Expression *OrOrExp::optimize(int result, bool keepLvalue)
|
||||
}
|
||||
else
|
||||
{
|
||||
e2 = e2->optimize(WANTflags | (result & WANTinterpret));
|
||||
e2 = e2->optimize(WANTflags);
|
||||
if (result && e2->type->toBasetype()->ty == Tvoid && !global.errors)
|
||||
{
|
||||
error("void has no value");
|
||||
return new ErrorExp();
|
||||
}
|
||||
if (e1->isConst())
|
||||
{
|
||||
if (e2->isConst())
|
||||
@@ -1165,8 +1182,8 @@ Expression *CmpExp::optimize(int result, bool keepLvalue)
|
||||
{ Expression *e;
|
||||
|
||||
//printf("CmpExp::optimize() %s\n", toChars());
|
||||
e1 = e1->optimize(WANTvalue | (result & WANTinterpret));
|
||||
e2 = e2->optimize(WANTvalue | (result & WANTinterpret));
|
||||
e1 = e1->optimize(WANTvalue);
|
||||
e2 = e2->optimize(WANTvalue);
|
||||
|
||||
Expression *e1 = fromConstInitializer(result, this->e1);
|
||||
Expression *e2 = fromConstInitializer(result, this->e2);
|
||||
@@ -1193,7 +1210,7 @@ Expression *CatExp::optimize(int result, bool keepLvalue)
|
||||
Expression *CondExp::optimize(int result, bool keepLvalue)
|
||||
{ Expression *e;
|
||||
|
||||
econd = econd->optimize(WANTflags | (result & WANTinterpret));
|
||||
econd = econd->optimize(WANTflags);
|
||||
if (econd->isBool(TRUE))
|
||||
e = e1->optimize(result, keepLvalue);
|
||||
else if (econd->isBool(FALSE))
|
||||
|
||||
Reference in New Issue
Block a user