From de4bcd15f0e0d0115db6b53c609c952488bf060e Mon Sep 17 00:00:00 2001 From: k-hara Date: Sat, 1 Nov 2014 23:07:17 +0900 Subject: [PATCH] [Refactoring] fix code style in ctfe interpreter --- src/constfold.c | 283 ++++++++++++++++++--------- src/ctfeexpr.c | 495 ++++++++++++++++++++++++++---------------------- src/interpret.c | 354 ++++++++++++++++++---------------- 3 files changed, 660 insertions(+), 472 deletions(-) diff --git a/src/constfold.c b/src/constfold.c index 262c1e2c1085..3ca931f6f964 100644 --- a/src/constfold.c +++ b/src/constfold.c @@ -44,7 +44,7 @@ Expression *expType(Type *type, Expression *e) int isConst(Expression *e) { //printf("Expression::isConst(): %s\n", e->toChars()); - switch(e->op) + switch (e->op) { case TOKint64: case TOKfloat64: @@ -70,7 +70,8 @@ int isConst(Expression *e) /* ========================================================================== */ Expression *Neg(Type *type, Expression *e1) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; if (e1->type->isreal()) @@ -91,7 +92,8 @@ Expression *Neg(Type *type, Expression *e1) } Expression *Com(Type *type, Expression *e1) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; e = new IntegerExp(loc, ~e1->toInteger(), type); @@ -99,7 +101,8 @@ Expression *Com(Type *type, Expression *e1) } Expression *Not(Type *type, Expression *e1) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; e = new IntegerExp(loc, e1->isBool(0), type); @@ -107,7 +110,8 @@ Expression *Not(Type *type, Expression *e1) } Expression *Bool(Type *type, Expression *e1) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; e = new IntegerExp(loc, e1->isBool(1), type); @@ -115,7 +119,8 @@ Expression *Bool(Type *type, Expression *e1) } Expression *Add(Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; #if LOG @@ -145,27 +150,33 @@ Expression *Add(Type *type, Expression *e1, Expression *e2) int x; if (e1->type->isreal()) - { r1 = e1->toReal(); + { + r1 = e1->toReal(); x = 0; } else if (e1->type->isimaginary()) - { i1 = e1->toImaginary(); + { + i1 = e1->toImaginary(); x = 3; } else - { c1 = e1->toComplex(); + { + c1 = e1->toComplex(); x = 6; } if (e2->type->isreal()) - { r2 = e2->toReal(); + { + r2 = e2->toReal(); } else if (e2->type->isimaginary()) - { i2 = e2->toImaginary(); + { + i2 = e2->toImaginary(); x += 1; } else - { c2 = e2->toComplex(); + { + c2 = e2->toComplex(); x += 2; } @@ -203,7 +214,8 @@ Expression *Add(Type *type, Expression *e1, Expression *e2) Expression *Min(Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; if (type->isreal()) @@ -230,27 +242,33 @@ Expression *Min(Type *type, Expression *e1, Expression *e2) int x; if (e1->type->isreal()) - { r1 = e1->toReal(); + { + r1 = e1->toReal(); x = 0; } else if (e1->type->isimaginary()) - { i1 = e1->toImaginary(); + { + i1 = e1->toImaginary(); x = 3; } else - { c1 = e1->toComplex(); + { + c1 = e1->toComplex(); x = 6; } if (e2->type->isreal()) - { r2 = e2->toReal(); + { + r2 = e2->toReal(); } else if (e2->type->isimaginary()) - { i2 = e2->toImaginary(); + { + i2 = e2->toImaginary(); x += 1; } else - { c2 = e2->toComplex(); + { + c2 = e2->toComplex(); x += 2; } @@ -283,11 +301,13 @@ Expression *Min(Type *type, Expression *e1, Expression *e2) } Expression *Mul(Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; if (type->isfloating()) - { complex_t c; + { + complex_t c; d_float80 r; if (e1->type->isreal()) @@ -334,11 +354,13 @@ Expression *Mul(Type *type, Expression *e1, Expression *e2) } Expression *Div(Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; if (type->isfloating()) - { complex_t c; + { + complex_t c; d_float80 r; //e1->type->print(); @@ -375,14 +397,16 @@ Expression *Div(Type *type, Expression *e1, Expression *e2) assert(0); } else - { sinteger_t n1; + { + sinteger_t n1; sinteger_t n2; sinteger_t n; n1 = e1->toInteger(); n2 = e2->toInteger(); if (n2 == 0) - { e2->error("divide by 0"); + { + e2->error("divide by 0"); e2 = new IntegerExp(loc, 1, e2->type); n2 = 1; } @@ -396,7 +420,8 @@ Expression *Div(Type *type, Expression *e1, Expression *e2) } Expression *Mod(Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; if (type->isfloating()) @@ -404,12 +429,14 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2) complex_t c; if (e2->type->isreal()) - { real_t r2 = e2->toReal(); + { + real_t r2 = e2->toReal(); c = complex_t(Port::fmodl(e1->toReal(), r2), Port::fmodl(e1->toImaginary(), r2)); } else if (e2->type->isimaginary()) - { real_t i2 = e2->toImaginary(); + { + real_t i2 = e2->toImaginary(); c = complex_t(Port::fmodl(e1->toReal(), i2), Port::fmodl(e1->toImaginary(), i2)); } @@ -426,19 +453,22 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2) assert(0); } else - { sinteger_t n1; + { + sinteger_t n1; sinteger_t n2; sinteger_t n; n1 = e1->toInteger(); n2 = e2->toInteger(); if (n2 == 0) - { e2->error("divide by 0"); + { + e2->error("divide by 0"); e2 = new IntegerExp(loc, 1, e2->type); n2 = 1; } if (n2 == -1 && !type->isunsigned()) - { // Check for int.min % -1 + { + // Check for int.min % -1 if (n1 == 0xFFFFFFFF80000000ULL && type->toBasetype()->ty != Tint64) { e2->error("integer overflow: int.min % -1"); @@ -462,7 +492,8 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2) } Expression *Pow(Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; // Handle integer power operations. @@ -536,7 +567,8 @@ Expression *Pow(Type *type, Expression *e1, Expression *e2) } Expression *Shl(Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type); @@ -651,13 +683,15 @@ Expression *And(Type *type, Expression *e1, Expression *e2) } Expression *Or(Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; e = new IntegerExp(e1->loc, e1->toInteger() | e2->toInteger(), type); return e; } Expression *Xor(Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; e = new IntegerExp(e1->loc, e1->toInteger() ^ e2->toInteger(), type); return e; } @@ -665,7 +699,8 @@ Expression *Xor(Type *type, Expression *e1, Expression *e2) /* Also returns EXP_CANT_INTERPRET if cannot be computed. */ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; int cmp = 0; real_t r1; @@ -680,11 +715,13 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) if (e2->op == TOKnull) cmp = 1; else if (e2->op == TOKstring) - { StringExp *es2 = (StringExp *)e2; + { + StringExp *es2 = (StringExp *)e2; cmp = (0 == es2->len); } else if (e2->op == TOKarrayliteral) - { ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; + { + ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; cmp = !es2->elements || (0 == es2->elements->dim); } else @@ -693,18 +730,21 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) else if (e2->op == TOKnull) { if (e1->op == TOKstring) - { StringExp *es1 = (StringExp *)e1; + { + StringExp *es1 = (StringExp *)e1; cmp = (0 == es1->len); } else if (e1->op == TOKarrayliteral) - { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; + { + ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; cmp = !es1->elements || (0 == es1->elements->dim); } else return EXP_CANT_INTERPRET; } else if (e1->op == TOKstring && e2->op == TOKstring) - { StringExp *es1 = (StringExp *)e1; + { + StringExp *es1 = (StringExp *)e1; StringExp *es2 = (StringExp *)e2; if (es1->sz != es2->sz) @@ -719,7 +759,8 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) cmp = 0; } else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral) - { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; + { + ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; if ((!es1->elements || !es1->elements->dim) && @@ -732,7 +773,8 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) else { for (size_t i = 0; i < es1->elements->dim; i++) - { Expression *ee1 = (*es1->elements)[i]; + { + Expression *ee1 = (*es1->elements)[i]; Expression *ee2 = (*es2->elements)[i]; Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); @@ -745,7 +787,8 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) } } else if (e1->op == TOKarrayliteral && e2->op == TOKstring) - { // Swap operands and use common code + { + // Swap operands and use common code Expression *etmp = e1; e1 = e2; e2 = etmp; @@ -776,7 +819,8 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) } } else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral) - { StructLiteralExp *es1 = (StructLiteralExp *)e1; + { + StructLiteralExp *es1 = (StructLiteralExp *)e1; StructLiteralExp *es2 = (StructLiteralExp *)e2; if (es1->sd != es2->sd) @@ -792,13 +836,15 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) { cmp = 1; for (size_t i = 0; i < es1->elements->dim; i++) - { Expression *ee1 = (*es1->elements)[i]; + { + Expression *ee1 = (*es1->elements)[i]; Expression *ee2 = (*es2->elements)[i]; if (ee1 == ee2) continue; if (!ee1 || !ee2) - { cmp = 0; + { + cmp = 0; break; } Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); @@ -816,7 +862,9 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) } } else if (e1->isConst() != 1 || e2->isConst() != 1) + { return EXP_CANT_INTERPRET; + } else if (e1->type->isreal()) { r1 = e1->toReal(); @@ -847,6 +895,7 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) } else return EXP_CANT_INTERPRET; + if (op == TOKnotequal) cmp ^= 1; e = new IntegerExp(loc, cmp, type); @@ -901,7 +950,8 @@ Expression *Identity(TOK op, Type *type, Expression *e1, Expression *e2) Expression *Cmp(TOK op, Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; dinteger_t n; real_t r1; @@ -910,7 +960,8 @@ Expression *Cmp(TOK op, Type *type, Expression *e1, Expression *e2) //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); if (e1->op == TOKstring && e2->op == TOKstring) - { StringExp *es1 = (StringExp *)e1; + { + StringExp *es1 = (StringExp *)e1; StringExp *es2 = (StringExp *)e2; size_t sz = es1->sz; assert(sz == es2->sz); @@ -944,7 +995,9 @@ Expression *Cmp(TOK op, Type *type, Expression *e1, Expression *e2) } } else if (e1->isConst() != 1 || e2->isConst() != 1) + { return EXP_CANT_INTERPRET; + } else if (e1->type->isreal()) { r1 = e1->toReal(); @@ -1008,7 +1061,8 @@ Expression *Cmp(TOK op, Type *type, Expression *e1, Expression *e2) assert(0); } else - { sinteger_t n1; + { + sinteger_t n1; sinteger_t n2; n1 = e1->toInteger(); @@ -1068,7 +1122,8 @@ Expression *Cmp(TOK op, Type *type, Expression *e1, Expression *e2) */ Expression *Cast(Type *type, Type *to, Expression *e1) -{ Expression *e = EXP_CANT_INTERPRET; +{ + Expression *e = EXP_CANT_INTERPRET; Loc loc = e1->loc; //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars()); @@ -1077,14 +1132,18 @@ Expression *Cast(Type *type, Type *to, Expression *e1) return e1; if (e1->type->implicitConvTo(to) >= MATCHconst || to->implicitConvTo(e1->type) >= MATCHconst) + { return expType(to, e1); + } // Allow covariant converions of delegates // (Perhaps implicit conversion from pure to impure should be a MATCHconst, // then we wouldn't need this extra check.) if (e1->type->toBasetype()->ty == Tdelegate && e1->type->implicitConvTo(to) == MATCHconvert) + { return expType(to, e1); + } Type *tb = to->toBasetype(); Type *typeb = type->toBasetype(); @@ -1107,11 +1166,14 @@ Expression *Cast(Type *type, Type *to, Expression *e1) return EXP_CANT_INTERPRET; if (tb->ty == Tbool) + { e = new IntegerExp(loc, e1->toInteger() != 0, type); + } else if (type->isintegral()) { if (e1->type->isfloating()) - { dinteger_t result; + { + dinteger_t result; real_t r = e1->toReal(); switch (typeb->ty) @@ -1139,26 +1201,34 @@ Expression *Cast(Type *type, Type *to, Expression *e1) e = new IntegerExp(loc, e1->toInteger(), type); } else if (tb->isreal()) - { real_t value = e1->toReal(); + { + real_t value = e1->toReal(); e = new RealExp(loc, value, type); } else if (tb->isimaginary()) - { real_t value = e1->toImaginary(); + { + real_t value = e1->toImaginary(); e = new RealExp(loc, value, type); } else if (tb->iscomplex()) - { complex_t value = e1->toComplex(); + { + complex_t value = e1->toComplex(); e = new ComplexExp(loc, value, type); } else if (tb->isscalar()) + { e = new IntegerExp(loc, e1->toInteger(), type); + } else if (tb->ty == Tvoid) + { e = EXP_CANT_INTERPRET; + } else if (tb->ty == Tstruct && e1->op == TOKint64) - { // Struct = 0; + { + // Struct = 0; StructDeclaration *sd = tb->toDsymbol(NULL)->isStructDeclaration(); assert(sd); Expressions *elements = new Expressions; @@ -1185,29 +1255,35 @@ Expression *Cast(Type *type, Type *to, Expression *e1) Expression *ArrayLength(Type *type, Expression *e1) -{ Expression *e; +{ + Expression *e; Loc loc = e1->loc; if (e1->op == TOKstring) - { StringExp *es1 = (StringExp *)e1; + { + StringExp *es1 = (StringExp *)e1; e = new IntegerExp(loc, es1->len, type); } else if (e1->op == TOKarrayliteral) - { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; + { + ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; size_t dim; dim = ale->elements ? ale->elements->dim : 0; e = new IntegerExp(loc, dim, type); } else if (e1->op == TOKassocarrayliteral) - { AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e1; + { + AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e1; size_t dim = ale->keys->dim; e = new IntegerExp(loc, dim, type); } else if (e1->type->toBasetype()->ty == Tsarray) + { e = ((TypeSArray *)e1->type->toBasetype())->dim; + } else e = EXP_CANT_INTERPRET; return e; @@ -1216,13 +1292,15 @@ Expression *ArrayLength(Type *type, Expression *e1) /* Also return EXP_CANT_INTERPRET if this fails */ Expression *Index(Type *type, Expression *e1, Expression *e2) -{ Expression *e = EXP_CANT_INTERPRET; +{ + Expression *e = EXP_CANT_INTERPRET; Loc loc = e1->loc; //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); assert(e1->type); if (e1->op == TOKstring && e2->op == TOKint64) - { StringExp *es1 = (StringExp *)e1; + { + StringExp *es1 = (StringExp *)e1; uinteger_t i = e2->toInteger(); if (i >= es1->len) @@ -1236,7 +1314,8 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) } } else if (e1->type->toBasetype()->ty == Tsarray && e2->op == TOKint64) - { TypeSArray *tsa = (TypeSArray *)e1->type->toBasetype(); + { + TypeSArray *tsa = (TypeSArray *)e1->type->toBasetype(); uinteger_t length = tsa->dim->toInteger(); uinteger_t i = e2->toInteger(); @@ -1246,7 +1325,8 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) e = new ErrorExp(); } else if (e1->op == TOKarrayliteral) - { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; + { + ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; e = (*ale->elements)[(size_t)i]; e->type = type; e->loc = loc; @@ -1259,14 +1339,16 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) uinteger_t i = e2->toInteger(); if (e1->op == TOKarrayliteral) - { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; + { + ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; if (i >= ale->elements->dim) { e1->error("array index %llu is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim); e = new ErrorExp(); } else - { e = (*ale->elements)[(size_t)i]; + { + e = (*ale->elements)[(size_t)i]; e->type = type; e->loc = loc; if (hasSideEffect(e)) @@ -1287,7 +1369,8 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) if (ex == EXP_CANT_INTERPRET) return ex; if (ex->isBool(true)) - { e = (*ae->values)[i]; + { + e = (*ae->values)[i]; e->type = type; e->loc = loc; if (hasSideEffect(e)) @@ -1302,19 +1385,22 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) /* Also return EXP_CANT_INTERPRET if this fails */ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) -{ Expression *e = EXP_CANT_INTERPRET; +{ + Expression *e = EXP_CANT_INTERPRET; Loc loc = e1->loc; #if LOG printf("Slice()\n"); if (lwr) - { printf("\te1 = %s\n", e1->toChars()); + { + printf("\te1 = %s\n", e1->toChars()); printf("\tlwr = %s\n", lwr->toChars()); printf("\tupr = %s\n", upr->toChars()); } #endif if (e1->op == TOKstring && lwr->op == TOKint64 && upr->op == TOKint64) - { StringExp *es1 = (StringExp *)e1; + { + StringExp *es1 = (StringExp *)e1; uinteger_t ilwr = lwr->toInteger(); uinteger_t iupr = upr->toInteger(); @@ -1344,7 +1430,8 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) else if (e1->op == TOKarrayliteral && lwr->op == TOKint64 && upr->op == TOKint64 && !hasSideEffect(e1)) - { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; + { + ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; uinteger_t ilwr = lwr->toInteger(); uinteger_t iupr = upr->toInteger(); @@ -1404,9 +1491,15 @@ void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *n unsigned value = (unsigned)((*newae->elements)[j]->toInteger()); switch (existingSE->sz) { - case 1: s[j+firstIndex] = (utf8_t)value; break; - case 2: ((unsigned short *)s)[j+firstIndex] = (unsigned short)value; break; - case 4: ((unsigned *)s)[j+firstIndex] = value; break; + case 1: + s[j + firstIndex] = (utf8_t)value; + break; + case 2: + ((unsigned short *)s)[j + firstIndex] = (unsigned short)value; + break; + case 4: + ((unsigned *)s)[j + firstIndex] = value; + break; default: assert(0); break; @@ -1452,9 +1545,15 @@ int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, si unsigned svalue; switch (sz) { - case 1: svalue = s[j + lo1]; break; - case 2: svalue = ((unsigned short *)s)[j+lo1]; break; - case 4: svalue = ((unsigned *)s)[j + lo1]; break; + case 1: + svalue = s[j + lo1]; + break; + case 2: + svalue = ((unsigned short *)s)[j+lo1]; + break; + case 4: + svalue = ((unsigned *)s)[j + lo1]; + break; default: assert(0); } @@ -1468,7 +1567,8 @@ int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, si /* Also return EXP_CANT_INTERPRET if this fails */ Expression *Cat(Type *type, Expression *e1, Expression *e2) -{ Expression *e = EXP_CANT_INTERPRET; +{ + Expression *e = EXP_CANT_INTERPRET; Loc loc = e1->loc; Type *t; Type *t1 = e1->type->toBasetype(); @@ -1478,12 +1578,14 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) //printf("\tt1 = %s, t2 = %s, type = %s\n", t1->toChars(), t2->toChars(), type->toChars()); if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral)) - { e = e2; + { + e = e2; t = t1; goto L2; } else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull) - { e = e1; + { + e = e1; t = t2; L2: Type *tn = e->type->toBasetype(); @@ -1514,7 +1616,8 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) e = es; } else - { // Create an ArrayLiteralExp + { + // Create an ArrayLiteralExp Expressions *elements = new Expressions(); elements->push(e); e = new ArrayLiteralExp(e->loc, elements); @@ -1750,18 +1853,21 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) goto L1; } else if (e1->op == TOKstring && e2->op == TOKnull) - { e = e1; + { + e = e1; t = e2->type; L1: Type *tb = t->toBasetype(); if (tb->ty == Tarray && tb->nextOf()->equals(e->type)) - { Expressions *expressions = new Expressions(); + { + Expressions *expressions = new Expressions(); expressions->push(e); e = new ArrayLiteralExp(loc, expressions); e->type = t; } if (!e->type->equals(type)) - { StringExp *se = (StringExp *)e->copy(); + { + StringExp *se = (StringExp *)e->copy(); e = se->castTo(NULL, type); } } @@ -1772,11 +1878,14 @@ Expression *Ptr(Type *type, Expression *e1) { //printf("Ptr(e1 = %s)\n", e1->toChars()); if (e1->op == TOKadd) - { AddExp *ae = (AddExp *)e1; + { + AddExp *ae = (AddExp *)e1; if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64) - { AddrExp *ade = (AddrExp *)ae->e1; + { + AddrExp *ade = (AddrExp *)ae->e1; if (ade->e1->op == TOKstructliteral) - { StructLiteralExp *se = (StructLiteralExp *)ade->e1; + { + StructLiteralExp *se = (StructLiteralExp *)ade->e1; unsigned offset = (unsigned)ae->e2->toInteger(); Expression *e = se->getField(type, offset); if (!e) diff --git a/src/ctfeexpr.c b/src/ctfeexpr.c index 8df1390c6590..3be11b0e9919 100644 --- a/src/ctfeexpr.c +++ b/src/ctfeexpr.c @@ -141,7 +141,7 @@ char *ThrownExceptionExp::toChars() void ThrownExceptionExp::generateUncaughtError() { Expression *e = (*thrown->value->elements)[0]; - StringExp* se = e->toStringExp(); + StringExp *se = e->toStringExp(); thrown->error("Uncaught CTFE exception %s(%s)", thrown->type->toChars(), se ? se->toChars() : e->toChars()); /* Also give the line where the throw statement was. We won't have it @@ -158,10 +158,14 @@ bool exceptionOrCantInterpret(Expression *e) { assert(EXP_CANT_INTERPRET && "EXP_CANT_INTERPRET must be distinct from " "null, Expression::init not called?"); - if (e == EXP_CANT_INTERPRET) return true; - if (!e || e == EXP_GOTO_INTERPRET || e == EXP_VOID_INTERPRET - || e == EXP_BREAK_INTERPRET || e == EXP_CONTINUE_INTERPRET) + if (e == EXP_CANT_INTERPRET) + return true; + if (!e || + e == EXP_GOTO_INTERPRET || e == EXP_VOID_INTERPRET || + e == EXP_BREAK_INTERPRET || e == EXP_CONTINUE_INTERPRET) + { return false; + } return e->op == TOKthrownexception; } @@ -234,7 +238,7 @@ Expression *copyLiteral(Expression *e) se2->ownedByCtfe = true; return se2; } - else if (e->op == TOKarrayliteral) + if (e->op == TOKarrayliteral) { ArrayLiteralExp *ae = (ArrayLiteralExp *)e; ArrayLiteralExp *r = new ArrayLiteralExp(e->loc, @@ -243,7 +247,7 @@ Expression *copyLiteral(Expression *e) r->ownedByCtfe = true; return r; } - else if (e->op == TOKassocarrayliteral) + if (e->op == TOKassocarrayliteral) { AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e; AssocArrayLiteralExp *r = new AssocArrayLiteralExp(e->loc, @@ -252,7 +256,7 @@ Expression *copyLiteral(Expression *e) r->ownedByCtfe = true; return r; } - else if (e->op == TOKstructliteral) + if (e->op == TOKstructliteral) { /* syntaxCopy doesn't work for struct literals, because of a nasty special * case: block assignment is permitted inside struct literals, eg, @@ -285,22 +289,22 @@ Expression *copyLiteral(Expression *e) StructLiteralExp *r = new StructLiteralExp(e->loc, se->sd, newelems, se->stype); r->type = e->type; r->ownedByCtfe = true; - r->origin = ((StructLiteralExp*)e)->origin; + r->origin = ((StructLiteralExp *)e)->origin; return r; } - else if (e->op == TOKfunction || e->op == TOKdelegate - || e->op == TOKsymoff || e->op == TOKnull - || e->op == TOKvar || e->op == TOKdotvar - || e->op == TOKint64 || e->op == TOKfloat64 - || e->op == TOKchar || e->op == TOKcomplex80 - || e->op == TOKvoid || e->op == TOKvector) + if (e->op == TOKfunction || e->op == TOKdelegate || + e->op == TOKsymoff || e->op == TOKnull || + e->op == TOKvar || e->op == TOKdotvar || + e->op == TOKint64 || e->op == TOKfloat64 || + e->op == TOKchar || e->op == TOKcomplex80 || + e->op == TOKvoid || e->op == TOKvector) { // Simple value types Expression *r = e->copy(); // keep e1 for DelegateExp and DotVarExp r->type = e->type; return r; } - else if (isPointer(e->type)) + if (isPointer(e->type)) { // For pointers, we only do a shallow copy. Expression *r; @@ -318,7 +322,7 @@ Expression *copyLiteral(Expression *e) r->type = e->type; return r; } - else if (e->op == TOKslice) + if (e->op == TOKslice) { // Array slices only do a shallow copy Expression *r = new SliceExp(e->loc, ((SliceExp *)e)->e1, @@ -326,16 +330,14 @@ Expression *copyLiteral(Expression *e) r->type = e->type; return r; } - else if (e->op == TOKclassreference) + if (e->op == TOKclassreference) return new ClassReferenceExp(e->loc, ((ClassReferenceExp *)e)->value, e->type); - else if (e->op == TOKerror) + if (e->op == TOKerror) return e; - else - { - e->error("Internal Compiler Error: CTFE literal %s", e->toChars()); - assert(0); - return e; - } + + e->error("Internal Compiler Error: CTFE literal %s", e->toChars()); + assert(0); + return e; } /* Deal with type painting. @@ -393,7 +395,7 @@ Expression *paintTypeOntoLiteral(Type *type, Expression *lit) { // Can't type paint from struct to struct*; this needs another // level of indirection - if (lit->op == TOKstructliteral && isPointer(type) ) + if (lit->op == TOKstructliteral && isPointer(type)) lit->error("CTFE internal error painting %s", type->toChars()); e = copyLiteral(lit); } @@ -403,10 +405,11 @@ Expression *paintTypeOntoLiteral(Type *type, Expression *lit) Expression *resolveSlice(Expression *e) { - if ( ((SliceExp *)e)->e1->op == TOKnull) - return ((SliceExp *)e)->e1; - return Slice(e->type, ((SliceExp *)e)->e1, - ((SliceExp *)e)->lwr, ((SliceExp *)e)->upr); + assert(e->op == TOKslice); + SliceExp *se = (SliceExp *)e; + if (se->e1->op == TOKnull) + return se->e1; + return Slice(e->type, se->e1, se->lwr, se->upr); } /* Determine the array length, without interpreting it. @@ -419,19 +422,23 @@ uinteger_t resolveArrayLength(Expression *e) if (e->op == TOKnull) return 0; if (e->op == TOKslice) - { uinteger_t ilo = ((SliceExp *)e)->lwr->toInteger(); + { + uinteger_t ilo = ((SliceExp *)e)->lwr->toInteger(); uinteger_t iup = ((SliceExp *)e)->upr->toInteger(); return iup - ilo; } if (e->op == TOKstring) - { return ((StringExp *)e)->len; + { + return ((StringExp *)e)->len; } if (e->op == TOKarrayliteral) - { ArrayLiteralExp *ale = (ArrayLiteralExp *)e; + { + ArrayLiteralExp *ale = (ArrayLiteralExp *)e; return ale->elements ? ale->elements->dim : 0; } if (e->op == TOKassocarrayliteral) - { AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e; + { + AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e; return ale->keys->dim; } assert(0); @@ -456,7 +463,8 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type, } bool mustCopy = needToCopyLiteral(elem); for (size_t i = 0; i < dim; i++) - { if (mustCopy) + { + if (mustCopy) elem = copyLiteral(elem); (*elements)[i] = elem; } @@ -517,8 +525,8 @@ TypeAArray *toBuiltinAAType(Type *t) bool isTypeInfo_Class(Type *type) { return type->ty == Tclass && - (( Type::dtypeinfo == ((TypeClass*)type)->sym) - || Type::dtypeinfo->isBaseOf(((TypeClass*)type)->sym, NULL)); + (Type::dtypeinfo == ((TypeClass *)type)->sym || + Type::dtypeinfo->isBaseOf(((TypeClass *)type)->sym, NULL)); } /************** Pointer operations ************************************/ @@ -533,8 +541,8 @@ bool isPointer(Type *t) // For CTFE only. Returns true if 'e' is true or a non-null pointer. int isTrueBool(Expression *e) { - return e->isBool(true) || ((e->type->ty == Tpointer || e->type->ty == Tclass) - && e->op != TOKnull); + return e->isBool(true) || + ((e->type->ty == Tpointer || e->type->ty == Tclass) && e->op != TOKnull); } /* Is it safe to convert from srcPointee* to destPointee* ? @@ -599,8 +607,8 @@ Expression *getAggregateFromPointer(Expression *e, dinteger_t *ofs) { IndexExp *ie = (IndexExp *)e; // Note that each AA element is part of its own memory block - if ((ie->e1->type->ty == Tarray || ie->e1->type->ty == Tsarray - || ie->e1->op == TOKstring || ie->e1->op==TOKarrayliteral) && + if ((ie->e1->type->ty == Tarray || ie->e1->type->ty == Tsarray || + ie->e1->op == TOKstring || ie->e1->op==TOKarrayliteral) && ie->e2->op == TOKint64) { *ofs = ie->e2->toInteger(); @@ -614,19 +622,31 @@ Expression *getAggregateFromPointer(Expression *e, dinteger_t *ofs) */ bool pointToSameMemoryBlock(Expression *agg1, Expression *agg2) { + if (agg1 == agg2) + return true; + // For integers cast to pointers, we regard them as non-comparable // unless they are identical. (This may be overly strict). - if (agg1->op == TOKint64 && agg2->op == TOKint64 - && agg1->toInteger() == agg2->toInteger()) + if (agg1->op == TOKint64 && agg2->op == TOKint64 && + agg1->toInteger() == agg2->toInteger()) + { return true; + } // Note that type painting can occur with VarExp, so we // must compare the variables being pointed to. - return agg1 == agg2 || - (agg1->op == TOKvar && agg2->op == TOKvar && - ((VarExp *)agg1)->var == ((VarExp *)agg2)->var) || - (agg1->op == TOKsymoff && agg2->op == TOKsymoff && - ((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var); + if (agg1->op == TOKvar && agg2->op == TOKvar && + ((VarExp *)agg1)->var == ((VarExp *)agg2)->var) + { + return true; + } + if (agg1->op == TOKsymoff && agg2->op == TOKsymoff && + ((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var) + { + return true; + } + + return false; } // return e1 - e2 as an integer, or error if not possible @@ -639,21 +659,21 @@ Expression *pointerDifference(Loc loc, Type *type, Expression *e1, Expression *e { Type *pointee = ((TypePointer *)agg1->type)->next; dinteger_t sz = pointee->size(); - return new IntegerExp(loc, (ofs1-ofs2)*sz, type); + return new IntegerExp(loc, (ofs1 - ofs2) * sz, type); } - else if (agg1->op == TOKstring && agg2->op == TOKstring) + if (agg1->op == TOKstring && agg2->op == TOKstring) { if (((StringExp *)agg1)->string == ((StringExp *)agg2)->string) { Type *pointee = ((TypePointer *)agg1->type)->next; dinteger_t sz = pointee->size(); - return new IntegerExp(loc, (ofs1-ofs2)*sz, type); + return new IntegerExp(loc, (ofs1 - ofs2) * sz, type); } } else if (agg1->op == TOKsymoff && agg2->op == TOKsymoff && - ((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var) + ((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var) { - return new IntegerExp(loc, ofs1-ofs2, type); + return new IntegerExp(loc, ofs1 - ofs2, type); } error(loc, "%s - %s cannot be interpreted at compile time: cannot subtract " "pointers to two different memory blocks", @@ -746,10 +766,10 @@ Expression *pointerArithmetic(Loc loc, TOK op, Type *type, int comparePointers(Loc loc, TOK op, Type *type, Expression *agg1, dinteger_t ofs1, Expression *agg2, dinteger_t ofs2) { - if ( pointToSameMemoryBlock(agg1, agg2) ) + if (pointToSameMemoryBlock(agg1, agg2)) { int n; - switch(op) + switch (op) { case TOKlt: n = (ofs1 < ofs2); break; case TOKle: n = (ofs1 <= ofs2); break; @@ -764,18 +784,18 @@ int comparePointers(Loc loc, TOK op, Type *type, Expression *agg1, dinteger_t of } return n; } - bool null1 = ( agg1->op == TOKnull ); - bool null2 = ( agg2->op == TOKnull ); + bool null1 = (agg1->op == TOKnull); + bool null2 = (agg2->op == TOKnull); int cmp; if (null1 || null2) { switch (op) { - case TOKlt: cmp = null1 && !null2; break; - case TOKgt: cmp = !null1 && null2; break; - case TOKle: cmp = null1; break; - case TOKge: cmp = null2; break; + case TOKlt: cmp = null1 && !null2; break; + case TOKgt: cmp = !null1 && null2; break; + case TOKle: cmp = null1; break; + case TOKge: cmp = null2; break; case TOKidentity: case TOKequal: case TOKnotidentity: // 'cmp' gets inverted below @@ -788,7 +808,7 @@ int comparePointers(Loc loc, TOK op, Type *type, Expression *agg1, dinteger_t of } else { - switch(op) + switch (op) { case TOKidentity: case TOKequal: @@ -809,9 +829,9 @@ int comparePointers(Loc loc, TOK op, Type *type, Expression *agg1, dinteger_t of // floating point -> integer or integer -> floating point bool isFloatIntPaint(Type *to, Type *from) { - return (from->size() == to->size()) && - ( (from->isintegral() && to->isfloating()) - || (from->isfloating() && to->isintegral()) ); + return from->size() == to->size() && + (from->isintegral() && to->isfloating() || + from->isfloating() && to->isintegral()); } // Reinterpret float/int value 'fromVal' as a float/integer of type 'to'. @@ -873,151 +893,158 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp result = e1->getInteger() * e2->getInteger(); break; case TOKdiv: - { - sinteger_t n1 = e1->getInteger(); - sinteger_t n2 = e2->getInteger(); + { + sinteger_t n1 = e1->getInteger(); + sinteger_t n2 = e2->getInteger(); - if (n2 == 0) - { e2->error("divide by 0"); - result = 1; - } - else if (e1->type->isunsigned() || e2->type->isunsigned()) - result = ((d_uns64) n1) / ((d_uns64) n2); - else - result = n1 / n2; + if (n2 == 0) + { + e2->error("divide by 0"); + result = 1; } + else if (e1->type->isunsigned() || e2->type->isunsigned()) + result = ((d_uns64) n1) / ((d_uns64) n2); + else + result = n1 / n2; break; + } case TOKmod: - { sinteger_t n1 = e1->getInteger(); - sinteger_t n2 = e2->getInteger(); + { + sinteger_t n1 = e1->getInteger(); + sinteger_t n2 = e2->getInteger(); - if (n2 == 0) - { e2->error("divide by 0"); + if (n2 == 0) + { + e2->error("divide by 0"); + n2 = 1; + } + if (n2 == -1 && !type->isunsigned()) + { + // Check for int.min % -1 + if (n1 == 0xFFFFFFFF80000000ULL && type->toBasetype()->ty != Tint64) + { + e2->error("integer overflow: int.min % -1"); n2 = 1; } - if (n2 == -1 && !type->isunsigned()) - { // Check for int.min % -1 - if (n1 == 0xFFFFFFFF80000000ULL && type->toBasetype()->ty != Tint64) - { - e2->error("integer overflow: int.min % -1"); - n2 = 1; - } - else if (n1 == 0x8000000000000000LL) // long.min % -1 - { - e2->error("integer overflow: long.min % -1"); - n2 = 1; - } + else if (n1 == 0x8000000000000000LL) // long.min % -1 + { + e2->error("integer overflow: long.min % -1"); + n2 = 1; } - if (e1->type->isunsigned() || e2->type->isunsigned()) - result = ((d_uns64) n1) % ((d_uns64) n2); - else - result = n1 % n2; } + if (e1->type->isunsigned() || e2->type->isunsigned()) + result = ((d_uns64) n1) % ((d_uns64) n2); + else + result = n1 % n2; break; + } case TOKpow: - { dinteger_t n = e2->getInteger(); - if (!e2->type->isunsigned() && (sinteger_t)n < 0) - { - e2->error("integer ^^ -integer: total loss of precision"); - n = 1; - } - uinteger_t r = e1->getInteger(); - result = 1; - while (n != 0) - { - if (n & 1) - result = result * r; - n >>= 1; - r = r * r; - } + { + dinteger_t n = e2->getInteger(); + if (!e2->type->isunsigned() && (sinteger_t)n < 0) + { + e2->error("integer ^^ -integer: total loss of precision"); + n = 1; + } + uinteger_t r = e1->getInteger(); + result = 1; + while (n != 0) + { + if (n & 1) + result = result * r; + n >>= 1; + r = r * r; } break; + } case TOKshl: result = e1->getInteger() << e2->getInteger(); break; case TOKshr: - { dinteger_t value = e1->getInteger(); - dinteger_t dcount = e2->getInteger(); - assert(dcount <= 0xFFFFFFFF); - unsigned count = (unsigned)dcount; - switch (e1->type->toBasetype()->ty) - { - case Tint8: - result = (d_int8)(value) >> count; - break; - - case Tuns8: - case Tchar: - result = (d_uns8)(value) >> count; - break; - - case Tint16: - result = (d_int16)(value) >> count; - break; - - case Tuns16: - case Twchar: - result = (d_uns16)(value) >> count; - break; - - case Tint32: - result = (d_int32)(value) >> count; - break; - - case Tuns32: - case Tdchar: - result = (d_uns32)(value) >> count; - break; - - case Tint64: - result = (d_int64)(value) >> count; - break; - - case Tuns64: - result = (d_uns64)(value) >> count; - break; - default: - assert(0); - } + { + dinteger_t value = e1->getInteger(); + dinteger_t dcount = e2->getInteger(); + assert(dcount <= 0xFFFFFFFF); + unsigned count = (unsigned)dcount; + switch (e1->type->toBasetype()->ty) + { + case Tint8: + result = (d_int8)(value) >> count; + break; + + case Tuns8: + case Tchar: + result = (d_uns8)(value) >> count; + break; + + case Tint16: + result = (d_int16)(value) >> count; + break; + + case Tuns16: + case Twchar: + result = (d_uns16)(value) >> count; + break; + + case Tint32: + result = (d_int32)(value) >> count; + break; + + case Tuns32: + case Tdchar: + result = (d_uns32)(value) >> count; + break; + + case Tint64: + result = (d_int64)(value) >> count; + break; + + case Tuns64: + result = (d_uns64)(value) >> count; + break; + default: + assert(0); } break; + } case TOKushr: - { dinteger_t value = e1->getInteger(); - dinteger_t dcount = e2->getInteger(); - assert(dcount <= 0xFFFFFFFF); - unsigned count = (unsigned)dcount; - switch (e1->type->toBasetype()->ty) - { - case Tint8: - case Tuns8: - case Tchar: - // Possible only with >>>=. >>> always gets promoted to int. - result = (value & 0xFF) >> count; - break; - - case Tint16: - case Tuns16: - case Twchar: - // Possible only with >>>=. >>> always gets promoted to int. - result = (value & 0xFFFF) >> count; - break; - - case Tint32: - case Tuns32: - case Tdchar: - result = (value & 0xFFFFFFFF) >> count; - break; - - case Tint64: - case Tuns64: - result = (d_uns64)(value) >> count; - break; - - default: - assert(0); - } + { + dinteger_t value = e1->getInteger(); + dinteger_t dcount = e2->getInteger(); + assert(dcount <= 0xFFFFFFFF); + unsigned count = (unsigned)dcount; + switch (e1->type->toBasetype()->ty) + { + case Tint8: + case Tuns8: + case Tchar: + // Possible only with >>>=. >>> always gets promoted to int. + result = (value & 0xFF) >> count; + break; + + case Tint16: + case Tuns16: + case Twchar: + // Possible only with >>>=. >>> always gets promoted to int. + result = (value & 0xFFFF) >> count; + break; + + case Tint32: + case Tuns32: + case Tdchar: + result = (value & 0xFFFFFFFF) >> count; + break; + + case Tint64: + case Tuns64: + result = (d_uns64)(value) >> count; + break; + + default: + assert(0); } break; + } case TOKequal: case TOKidentity: result = (e1->getInteger() == e2->getInteger()); @@ -1179,16 +1206,18 @@ int ctfeCmpArrays(Loc loc, Expression *e1, Expression *e2, uinteger_t len) Expression *x = e1; if (x->op == TOKslice) - { lo1 = ((SliceExp *)x)->lwr->toInteger(); - x = ((SliceExp*)x)->e1; + { + lo1 = ((SliceExp *)x)->lwr->toInteger(); + x = ((SliceExp *)x)->e1; } StringExp *se1 = (x->op == TOKstring) ? (StringExp *)x : NULL; ArrayLiteralExp *ae1 = (x->op == TOKarrayliteral) ? (ArrayLiteralExp *)x : NULL; x = e2; if (x->op == TOKslice) - { lo2 = ((SliceExp *)x)->lwr->toInteger(); - x = ((SliceExp*)x)->e1; + { + lo2 = ((SliceExp *)x)->lwr->toInteger(); + x = ((SliceExp *)x)->e1; } StringExp *se2 = (x->op == TOKstring) ? (StringExp *)x : NULL; ArrayLiteralExp *ae2 = (x->op == TOKarrayliteral) ? (ArrayLiteralExp *)x : NULL; @@ -1207,17 +1236,20 @@ int ctfeCmpArrays(Loc loc, Expression *e1, Expression *e2, uinteger_t len) // a full cmp. bool needCmp = ae1->type->nextOf()->isintegral(); for (size_t i = 0; i < len; i++) - { Expression *ee1 = (*ae1->elements)[(size_t)(lo1 + i)]; + { + Expression *ee1 = (*ae1->elements)[(size_t)(lo1 + i)]; Expression *ee2 = (*ae2->elements)[(size_t)(lo2 + i)]; if (needCmp) - { sinteger_t c = ee1->toInteger() - ee2->toInteger(); + { + sinteger_t c = ee1->toInteger() - ee2->toInteger(); if (c > 0) return 1; if (c < 0) return -1; } else - { if (ctfeRawCmp(loc, ee1, ee2)) + { + if (ctfeRawCmp(loc, ee1, ee2)) return 1; } } @@ -1251,7 +1283,8 @@ bool isArray(Expression *e) int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2) { if (e1->op == TOKclassreference || e2->op == TOKclassreference) - { if (e1->op == TOKclassreference && e2->op == TOKclassreference && + { + if (e1->op == TOKclassreference && e2->op == TOKclassreference && ((ClassReferenceExp *)e1)->value == ((ClassReferenceExp *)e2)->value) return 0; return 1; @@ -1271,7 +1304,8 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2) Expression *agg2 = getAggregateFromPointer(e2, &ofs2); if ((agg1 == agg2) || (agg1->op == TOKvar && agg2->op == TOKvar && ((VarExp *)agg1)->var == ((VarExp *)agg2)->var)) - { if (ofs1 == ofs2) + { + if (ofs1 == ofs2) return 0; } return 1; @@ -1311,8 +1345,8 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2) uinteger_t len2 = resolveArrayLength(e2); // workaround for dmc optimizer bug calculating wrong len for // uinteger_t len = (len1 < len2 ? len1 : len2); - // if(len == 0) ... - if(len1 > 0 && len2 > 0) + // if (len == 0) ... + if (len1 > 0 && len2 > 0) { uinteger_t len = (len1 < len2 ? len1 : len2); int res = ctfeCmpArrays(loc, e1, e2, len); @@ -1353,7 +1387,8 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2) } if (e1->op == TOKstructliteral && e2->op == TOKstructliteral) - { StructLiteralExp *es1 = (StructLiteralExp *)e1; + { + StructLiteralExp *es1 = (StructLiteralExp *)e1; StructLiteralExp *es2 = (StructLiteralExp *)e2; // For structs, we only need to return 0 or 1 (< and > aren't legal). @@ -1369,7 +1404,8 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2) else { for (size_t i = 0; i < es1->elements->dim; i++) - { Expression *ee1 = (*es1->elements)[i]; + { + Expression *ee1 = (*es1->elements)[i]; Expression *ee2 = (*es2->elements)[i]; if (ee1 == ee2) @@ -1459,7 +1495,8 @@ int ctfeIdentity(Loc loc, TOK op, Expression *e1, Expression *e2) else if (e1->type->isimaginary()) cmp = RealEquals(e1->toImaginary(), e2->toImaginary()); else if (e1->type->iscomplex()) - { complex_t v1 = e1->toComplex(); + { + complex_t v1 = e1->toComplex(); complex_t v2 = e2->toComplex(); cmp = RealEquals(creall(v1), creall(v2)) && RealEquals(cimagl(v1), cimagl(v1)); @@ -1558,7 +1595,7 @@ Expression *ctfeCat(Type *type, Expression *e1, Expression *e2) e = es; return e; } - else if (e1->op == TOKstring && e2->op == TOKarrayliteral && + if (e1->op == TOKstring && e2->op == TOKarrayliteral && t2->nextOf()->isintegral()) { // string ~ [chars] => string (only valid for CTFE) @@ -1589,7 +1626,7 @@ Expression *ctfeCat(Type *type, Expression *e1, Expression *e2) e = es; return e; } - else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral && + if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral && t1->nextOf()->equals(t2->nextOf())) { // [ e1 ] ~ [ e2 ] ---> [ e1, e2 ] @@ -1602,13 +1639,13 @@ Expression *ctfeCat(Type *type, Expression *e1, Expression *e2) e->type = type; return e; } - else if (e1->op == TOKarrayliteral && e2->op == TOKnull && + if (e1->op == TOKarrayliteral && e2->op == TOKnull && t1->nextOf()->equals(t2->nextOf())) { // [ e1 ] ~ null ----> [ e1 ].dup return paintTypeOntoLiteral(type, copyLiteral(e1)); } - else if (e1->op == TOKnull && e2->op == TOKarrayliteral && + if (e1->op == TOKnull && e2->op == TOKarrayliteral && t1->nextOf()->equals(t2->nextOf())) { // null ~ [ e2 ] ----> [ e2 ].dup @@ -1771,8 +1808,9 @@ void recursiveBlockAssign(ArrayLiteralExp *ae, Expression *val, bool wantRef) Type *desttype = ((TypeArray *)ae->type)->next->toBasetype()->castMod(0); bool directblk = (val->type->toBasetype()->castMod(0))->equals(desttype); - bool cow = !(val->op == TOKstructliteral || val->op == TOKarrayliteral - || val->op == TOKstring); + bool cow = val->op != TOKstructliteral && + val->op != TOKarrayliteral && + val->op != TOKstring; for (size_t k = 0; k < ae->elements->dim; k++) { @@ -1831,7 +1869,8 @@ Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae, Expressions *valuesx = aae->values; int updated = 0; for (size_t j = valuesx->dim; j; ) - { j--; + { + j--; Expression *ekey = (*aae->keys)[j]; int eq = ctfeEqual(loc, TOKequal, ekey, index); if (eq) @@ -1841,7 +1880,8 @@ Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae, } } if (!updated) - { // Append index/newval to keysx[]/valuesx[] + { + // Append index/newval to keysx[]/valuesx[] valuesx->push(newval); keysx->push(index); } @@ -1863,7 +1903,8 @@ Expression *changeArrayLiteralLength(Loc loc, TypeArray *arrayType, // Resolve slices size_t indxlo = 0; if (oldval->op == TOKslice) - { indxlo = (size_t)((SliceExp *)oldval)->lwr->toInteger(); + { + indxlo = (size_t)((SliceExp *)oldval)->lwr->toInteger(); oldval = ((SliceExp *)oldval)->e1; } size_t copylen = oldlen < newlen ? oldlen : newlen; @@ -1898,7 +1939,8 @@ Expression *changeArrayLiteralLength(Loc loc, TypeArray *arrayType, for (size_t i = 0; i < copylen; i++) (*elements)[i] = (*ae->elements)[indxlo + i]; if (elemType->ty == Tstruct || elemType->ty == Tsarray) - { /* If it is an aggregate literal representing a value type, + { + /* If it is an aggregate literal representing a value type, * we need to create a unique copy for each element */ for (size_t i = copylen; i < newlen; i++) @@ -2011,17 +2053,19 @@ bool isCtfeValueValid(Expression *newval) if (newval->op == TOKassocarrayliteral) assert(((AssocArrayLiteralExp *)newval)->ownedByCtfe); - if ((newval->op ==TOKarrayliteral) || ( newval->op==TOKstructliteral) || - (newval->op==TOKstring) || (newval->op == TOKassocarrayliteral) || - (newval->op == TOKnull)) - { return true; + if (newval->op == TOKarrayliteral || newval->op == TOKstructliteral || + newval->op == TOKstring || newval->op == TOKassocarrayliteral || + newval->op == TOKnull) + { + return true; } // Dynamic arrays passed by ref may be null. When this happens // they may originate from an index or dotvar expression. if (newval->type->ty == Tarray || newval->type->ty == Taarray) + { if (newval->op == TOKdotvar || newval->op == TOKindex) return true; // actually must be null - + } if (newval->op == TOKslice) { SliceExp *se = (SliceExp *)newval; @@ -2047,13 +2091,15 @@ void showCtfeExpr(Expression *e, int level) StructDeclaration *sd = NULL; ClassDeclaration *cd = NULL; if (e->op == TOKstructliteral) - { elements = ((StructLiteralExp *)e)->elements; + { + elements = ((StructLiteralExp *)e)->elements; sd = ((StructLiteralExp *)e)->sd; printf("STRUCT type = %s %p:\n", e->type->toChars(), e); } else if (e->op == TOKclassreference) - { elements = ((ClassReferenceExp *)e)->value->elements; + { + elements = ((ClassReferenceExp *)e)->value->elements; cd = ((ClassReferenceExp *)e)->originalClass(); printf("CLASS type = %s %p:\n", e->type->toChars(), ((ClassReferenceExp *)e)->value); @@ -2103,9 +2149,11 @@ void showCtfeExpr(Expression *e, int level) { size_t fieldsSoFar = 0; for (size_t i = 0; i < elements->dim; i++) - { Expression *z = NULL; + { + Expression *z = NULL; VarDeclaration *v = NULL; - if (i > 15) { + if (i > 15) + { printf("...(total %d elements)\n", (int)elements->dim); return; } @@ -2178,7 +2226,7 @@ Expression *voidInitLiteral(Type *t, VarDeclaration *var) ae->ownedByCtfe = true; return ae; } - else if (t->ty == Tstruct) + if (t->ty == Tstruct) { TypeStruct *ts = (TypeStruct *)t; Expressions *exps = new Expressions(); @@ -2192,8 +2240,5 @@ Expression *voidInitLiteral(Type *t, VarDeclaration *var) se->ownedByCtfe = true; return se; } - else - { - return new VoidInitExp(var, t); - } + return new VoidInitExp(var, t); } diff --git a/src/interpret.c b/src/interpret.c index 8cb93c2b50e5..746097700a3a 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -184,9 +184,10 @@ void CtfeStack::setValue(VarDeclaration *v, Expression *e) void CtfeStack::push(VarDeclaration *v) { assert(!v->isDataseg() || v->isCTFE()); - if (v->ctfeAdrOnStack!= (size_t)-1 - && v->ctfeAdrOnStack >= framepointer) - { // Already exists in this frame, reuse it. + if (v->ctfeAdrOnStack != (size_t)-1 && + v->ctfeAdrOnStack >= framepointer) + { + // Already exists in this frame, reuse it. values[v->ctfeAdrOnStack] = NULL; return; } @@ -328,7 +329,7 @@ struct CompiledCtfeFunction { if (!td->objects) return; - for(size_t i= 0; i < td->objects->dim; ++i) + for (size_t i= 0; i < td->objects->dim; ++i) { RootObject *o = td->objects->tdata()[i]; Expression *ex = isExpression(o); @@ -1316,9 +1317,8 @@ class Interpreter : public Visitor Expression *m = (*elems)[i]; if (!m) continue; - if (m) - if ( !stopPointersEscaping(loc, m) ) - return false; + if (!stopPointersEscaping(loc, m)) + return false; } return true; } @@ -1875,9 +1875,10 @@ class Interpreter : public Visitor ClassReferenceExp *boss = oldest->thrown; assert((*boss->value->elements)[4]->type->ty == Tclass); ClassReferenceExp *collateral = newest->thrown; - if (isAnErrorException(collateral->originalClass()) - && !isAnErrorException(boss->originalClass())) - { // The new exception bypass the existing chain + if ( isAnErrorException(collateral->originalClass()) && + !isAnErrorException(boss->originalClass())) + { + // The new exception bypass the existing chain assert((*collateral->value->elements)[5]->type->ty == Tclass); (*collateral->value->elements)[5] = boss; return newest; @@ -2153,10 +2154,9 @@ class Interpreter : public Visitor { fromType = ((TypeArray *)(e->var->type))->next; } - if (e->var->isDataseg() && ( - (e->offset == 0 && isSafePointerCast(e->var->type, pointee)) || - (fromType && isSafePointerCast(fromType, pointee)) - )) + if (e->var->isDataseg() && + ((e->offset == 0 && isSafePointerCast(e->var->type, pointee)) || + (fromType && isSafePointerCast(fromType, pointee)))) { result = e; return; @@ -2173,17 +2173,17 @@ class Interpreter : public Visitor Type *elemtype = ((TypeArray *)(val->type))->next; // It's OK to cast from fixed length to dynamic array, eg &int[3] to int[]* - if (val->type->ty == Tsarray && pointee->ty == Tarray - && elemtype->size() == pointee->nextOf()->size()) + if (val->type->ty == Tsarray && pointee->ty == Tarray && + elemtype->size() == pointee->nextOf()->size()) { result = new AddrExp(e->loc, val); result->type = e->type; return; } - if (!isSafePointerCast(elemtype, pointee) ) + if (!isSafePointerCast(elemtype, pointee)) { // It's also OK to cast from &string to string*. - if (e->offset == 0 && isSafePointerCast(e->var->type, pointee) ) + if (e->offset == 0 && isSafePointerCast(e->var->type, pointee)) { result = new VarExp(e->loc, e->var); result->type = e->type; @@ -2200,7 +2200,9 @@ class Interpreter : public Visitor assert(sz * indx == e->offset); Expression *aggregate = NULL; if (val->op == TOKarrayliteral || val->op == TOKstring) + { aggregate = val; + } else if (val->op == TOKslice) { aggregate = ((SliceExp *)val)->e1; @@ -2215,7 +2217,7 @@ class Interpreter : public Visitor return; } } - else if (e->offset == 0 && isSafePointerCast(e->var->type, pointee) ) + else if (e->offset == 0 && isSafePointerCast(e->var->type, pointee)) { // Create a CTFE pointer &var VarExp *ve = new VarExp(e->loc, e->var); @@ -2294,7 +2296,7 @@ class Interpreter : public Visitor // after 'out', 'ref', and 'this' have been removed. static Expression *resolveReferences(Expression *e) { - for(;;) + for (;;) { if (e->op == TOKthis) { @@ -2322,8 +2324,8 @@ class Interpreter : public Visitor e = val; continue; } - else if (val && (val->op == TOKindex || val->op == TOKdotvar - || val->op == TOKthis || val->op == TOKvar)) + if (val && (val->op == TOKindex || val->op == TOKdotvar || + val->op == TOKthis || val->op == TOKvar)) { e = val; continue; @@ -2357,9 +2359,11 @@ class Interpreter : public Visitor !hasValue(v) && v->init && !v->isCTFE()) { - if(v->scope && !v->inuse) + if (v->scope && !v->inuse) v->init = v->init->semantic(v->scope, v->type, INITinterpret); // might not be run on aggregate members - e = v->init->toExpression(v->type); + { + e = v->init->toExpression(v->type); + } if (v->inuse) { error(loc, "circular initialization of %s", v->toChars()); @@ -2395,7 +2399,7 @@ class Interpreter : public Visitor if (e && e != EXP_CANT_INTERPRET && e->op != TOKthrownexception) { e = copyLiteral(e); - if (v->isDataseg() || (v->storage_class & STCmanifest )) + if (v->isDataseg() || (v->storage_class & STCmanifest)) ctfeStack.saveGlobalConstant(v, e); } } @@ -2430,18 +2434,18 @@ class Interpreter : public Visitor if (!e && !v->isCTFE() && v->isDataseg()) { error(loc, "static variable %s cannot be read at compile time", v->toChars()); - e = EXP_CANT_INTERPRET; + return EXP_CANT_INTERPRET; } - else if (!e) + if (!e) { assert(!(v->init && v->init->isVoidInitializer())); // CTFE initiated from inside a function error(loc, "variable %s cannot be read at compile time", v->toChars()); return EXP_CANT_INTERPRET; } - else if (exceptionOrCantInterpret(e)) + if (exceptionOrCantInterpret(e)) return e; - else if (goal == ctfeNeedLvalue && v->isRef() && e->op == TOKindex) + if (goal == ctfeNeedLvalue && v->isRef() && e->op == TOKindex) { // If it is a foreach ref, resolve the index into a constant IndexExp *ie = (IndexExp *)e; @@ -2453,20 +2457,25 @@ class Interpreter : public Visitor } return e; } - else if ((goal == ctfeNeedLvalue) - || e->op == TOKstring || e->op == TOKstructliteral || e->op == TOKarrayliteral - || e->op == TOKassocarrayliteral || e->op == TOKslice - || e->type->toBasetype()->ty == Tpointer) + if (goal == ctfeNeedLvalue || + e->op == TOKstring || + e->op == TOKstructliteral || + e->op == TOKarrayliteral || + e->op == TOKassocarrayliteral || + e->op == TOKslice || + e->type->toBasetype()->ty == Tpointer) + { return e; // it's already an Lvalue - else if (e->op == TOKvoid) + } + if (e->op == TOKvoid) { VoidInitExp *ve = (VoidInitExp *)e; error(loc, "cannot read uninitialized variable %s in ctfe", v->toPrettyChars()); errorSupplemental(ve->var->loc, "%s was uninitialized and used before set", ve->var->toChars()); - e = EXP_CANT_INTERPRET; + return EXP_CANT_INTERPRET; } - else - e = e->interpret(istate, goal); + + e = e->interpret(istate, goal); } if (!e) e = EXP_CANT_INTERPRET; @@ -2502,7 +2511,7 @@ class Interpreter : public Visitor result = EXP_CANT_INTERPRET; return; } - else if (v && !hasValue(v)) + if (v && !hasValue(v)) { if (!v->isCTFE() && v->isDataseg()) e->error("static variable %s cannot be referenced at compile time", v->toChars()); @@ -2511,7 +2520,7 @@ class Interpreter : public Visitor result = EXP_CANT_INTERPRET; return; } - else if (v && hasValue(v) && getValue(v)->op == TOKvar) + if (v && hasValue(v) && getValue(v)->op == TOKvar) { // A ref of a reference, is the original reference result = getValue(v); @@ -2542,7 +2551,7 @@ class Interpreter : public Visitor TupleDeclaration *td = v->toAlias()->isTupleDeclaration(); if (!td->objects) return; - for(size_t i= 0; i < td->objects->dim; ++i) + for (size_t i= 0; i < td->objects->dim; ++i) { RootObject * o = (*td->objects)[i]; Expression *ex = isExpression(o); @@ -2730,7 +2739,7 @@ class Interpreter : public Visitor Expression *exp = (*e->elements)[i]; if (exp->op == TOKindex) // segfault bug 6250 - assert(((IndexExp*)exp)->e1 != e); + assert(((IndexExp *)exp)->e1 != e); Expression *ex = exp->interpret(istate); if (exceptionOrCantInterpret(ex)) { @@ -3195,7 +3204,7 @@ class Interpreter : public Visitor result = e1; return; } - switch(e->op) + switch (e->op) { case TOKneg: result = Neg(e->type, e1); break; case TOKtilde: result = Com(e->type, e1); break; @@ -3376,7 +3385,7 @@ class Interpreter : public Visitor void visit(BinExp *e) { - switch(e->op) + switch (e->op) { case TOKadd: interpretCommon(e, &Add); return; case TOKmin: interpretCommon(e, &Min); return; @@ -3432,13 +3441,13 @@ class Interpreter : public Visitor if (e->op == TOKvar) break; if (e->op == TOKindex) - e = ((IndexExp*)e)->e1; + e = ((IndexExp *)e)->e1; else if (e->op == TOKdotvar) e = ((DotVarExp *)e)->e1; else if (e->op == TOKdotti) e = ((DotTemplateInstanceExp *)e)->e1; else if (e->op == TOKslice) - e = ((SliceExp*)e)->e1; + e = ((SliceExp *)e)->e1; else return NULL; } @@ -3499,9 +3508,9 @@ class Interpreter : public Visitor // e = *x is never a reference, because *x is always a value if (!fp && e->e1->type->toBasetype()->equals(e->e2->type->toBasetype()) && - (e1->type->toBasetype()->ty == Tarray || isAssocArray(e1->type) - || e1->type->toBasetype()->ty == Tclass) - && e->e2->op != TOKstar) + (e1->type->toBasetype()->ty == Tarray || isAssocArray(e1->type) || + e1->type->toBasetype()->ty == Tclass) && + e->e2->op != TOKstar) { wantRef = true; // If it is assignment from a ref parameter, it's not a ref assignment @@ -3518,8 +3527,8 @@ class Interpreter : public Visitor } // If it is a construction of a ref variable, it is a ref assignment // (in fact, it is an lvalue reference assignment). - if (e->op == TOKconstruct && e->e1->op == TOKvar - && ((VarExp*)e->e1)->var->storage_class & STCref) + if (e->op == TOKconstruct && e->e1->op == TOKvar && + ((VarExp *)e->e1)->var->storage_class & STCref) { wantRef = true; wantLvalueRef = true; @@ -3573,8 +3582,8 @@ class Interpreter : public Visitor result = e1; return; } - if (!(e1->op == TOKvar || e1->op == TOKdotvar || e1->op == TOKindex - || e1->op == TOKslice || e1->op == TOKstructliteral)) + if (!(e1->op == TOKvar || e1->op == TOKdotvar || e1->op == TOKindex || + e1->op == TOKslice || e1->op == TOKstructliteral)) { e->error("cannot dereference invalid pointer %s", e->e1->toChars()); @@ -3583,8 +3592,8 @@ class Interpreter : public Visitor } } - if (!(e1->op == TOKarraylength || e1->op == TOKvar || e1->op == TOKdotvar - || e1->op == TOKindex || e1->op == TOKslice || e1->op == TOKstructliteral)) + if (!(e1->op == TOKarraylength || e1->op == TOKvar || e1->op == TOKdotvar || + e1->op == TOKindex || e1->op == TOKslice || e1->op == TOKstructliteral)) { e->error("CTFE internal error: unsupported assignment %s", e->toChars()); result = EXP_CANT_INTERPRET; @@ -3652,9 +3661,9 @@ class Interpreter : public Visitor } if (oldval->op == TOKslice) oldval = resolveSlice(oldval); - if (e->e1->type->ty == Tpointer && e->e2->type->isintegral() - && (e->op == TOKaddass || e->op == TOKminass || - e->op == TOKplusplus || e->op == TOKminusminus)) + if (e->e1->type->ty == Tpointer && e->e2->type->isintegral() && + (e->op == TOKaddass || e->op == TOKminass || + e->op == TOKplusplus || e->op == TOKminusminus)) { oldval = e->e1->interpret(istate, ctfeNeedLvalue); if (exceptionOrCantInterpret(oldval)) @@ -3868,7 +3877,8 @@ class Interpreter : public Visitor return; } if (aggregate->op == TOKassocarrayliteral) - { // Normal case, ultimate parent AA already exists + { + // Normal case, ultimate parent AA already exists // We need to walk from the deepest index up, checking that an AA literal // already exists on each level. Expression *index = ((IndexExp *)e1)->e2->interpret(istate); @@ -3970,8 +3980,8 @@ class Interpreter : public Visitor // pointer or reference // (in which case, we already have the lvalue). DotVarExp *dve = (DotVarExp *)e1; - bool isCtfePointer = (dve->e1->op == TOKstructliteral) - && ((StructLiteralExp *)(dve->e1))->ownedByCtfe; + bool isCtfePointer = (dve->e1->op == TOKstructliteral) && + ((StructLiteralExp *)(dve->e1))->ownedByCtfe; if (!isCtfePointer) { e1 = e1->interpret(istate, isPointer(e->type) ? ctfeNeedLvalueRef : ctfeNeedLvalue); @@ -4104,7 +4114,7 @@ class Interpreter : public Visitor assert(se->sd); int unionStart = se->sd->firstFieldInUnion(fieldi); int unionSize = se->sd->numFieldsInUnion(fieldi); - for(int i = unionStart; i < unionStart + unionSize; ++i) + for (int i = unionStart; i < unionStart + unionSize; ++i) { if (i == fieldi) continue; @@ -4179,8 +4189,9 @@ class Interpreter : public Visitor originalExp->error("cannot index null array %s", ie->e1->toChars()); return false; } - if (oldval->op != TOKarrayliteral && oldval->op != TOKstring - && oldval->op != TOKslice) + if (oldval->op != TOKarrayliteral && + oldval->op != TOKstring && + oldval->op != TOKslice) { originalExp->error("cannot determine length of %s at compile time", ie->e1->toChars()); @@ -4320,9 +4331,10 @@ class Interpreter : public Visitor assert(0); } } - if (wantRef && newval->op == TOKindex - && ((IndexExp *)newval)->e1 == aggregate) - { // It's a circular reference, resolve it now + if (wantRef && newval->op == TOKindex && + ((IndexExp *)newval)->e1 == aggregate) + { + // It's a circular reference, resolve it now newval = newval->interpret(istate); } @@ -4402,8 +4414,10 @@ class Interpreter : public Visitor else oldval = oldval->interpret(istate); - if (oldval->op != TOKarrayliteral && oldval->op != TOKstring - && oldval->op != TOKslice && oldval->op != TOKnull) + if (oldval->op != TOKarrayliteral && + oldval->op != TOKstring && + oldval->op != TOKslice && + oldval->op != TOKnull) { if (oldval->op == TOKsymoff) { @@ -4510,7 +4524,7 @@ class Interpreter : public Visitor } aggregate = sexpold->e1; } - if ( isPointer(aggregate->type) ) + if (isPointer(aggregate->type)) { // Slicing a pointer --> change the bounds aggregate = sexp->e1->interpret(istate, ctfeNeedLvalue); @@ -4550,8 +4564,8 @@ class Interpreter : public Visitor assert(0); } } - if (wantRef && newval->op == TOKindex - && ((IndexExp *)newval)->e1 == aggregate) + if (wantRef && newval->op == TOKindex && + ((IndexExp *)newval)->e1 == aggregate) { // It's a circular reference, resolve it now newval = newval->interpret(istate); @@ -4591,8 +4605,8 @@ class Interpreter : public Visitor sliceAssignStringFromString((StringExp *)existingSE, (StringExp *)newval, (size_t)firstIndex); return newval; } - else if (newval->op == TOKstring && existingAE - && existingAE->type->nextOf()->isintegral()) + else if (newval->op == TOKstring && existingAE && + existingAE->type->nextOf()->isintegral()) { /* Mixed slice: it was initialized as an array literal of chars/integers. * Now a slice of it is being set with a string. @@ -4645,8 +4659,9 @@ class Interpreter : public Visitor existingAE->type->ty == Tarray); Type *desttype = ((TypeArray *)existingAE->type)->next->toBasetype()->castMod(0); bool directblk = (e2->type->toBasetype()->castMod(0))->equals(desttype); - bool cow = !(newval->op == TOKstructliteral || newval->op == TOKarrayliteral - || newval->op == TOKstring); + bool cow = !(newval->op == TOKstructliteral || + newval->op == TOKarrayliteral || + newval->op == TOKstring); for (size_t j = 0; j < upperbound-lowerbound; j++) { if (!directblk) @@ -4690,7 +4705,7 @@ class Interpreter : public Visitor void visit(BinAssignExp *e) { - switch(e->op) + switch (e->op) { case TOKaddass: interpretAssignCommon(e, &Add); return; case TOKminass: interpretAssignCommon(e, &Min); return; @@ -4734,10 +4749,11 @@ class Interpreter : public Visitor { int ret = 1; while (e->op == TOKnot) - { ret *= -1; + { + ret *= -1; e = ((NotExp *)e)->e1; } - switch(e->op) + switch (e->op) { case TOKlt: case TOKle: @@ -4747,7 +4763,7 @@ class Interpreter : public Visitor case TOKge: *p1 = ((BinExp *)e)->e1; *p2 = ((BinExp *)e)->e2; - if ( !(isPointer((*p1)->type) && isPointer((*p2)->type)) ) + if (!(isPointer((*p1)->type) && isPointer((*p2)->type))) ret = 0; break; default: @@ -4761,7 +4777,7 @@ class Interpreter : public Visitor */ static TOK reverseRelation(TOK op) { - switch(op) + switch (op) { case TOKge: return TOKlt; case TOKgt: return TOKle; @@ -4786,7 +4802,7 @@ class Interpreter : public Visitor * the comparison operators can be any of >, <, <=, >=, provided that * both directions (p > q and p < q) are checked. Additionally the * relational sub-expressions can be negated, eg - * ( !(q1 < p1) && p2 <= q2 ) is valid. + * (!(q1 < p1) && p2 <= q2) is valid. */ void interpretFourPointerRelation(BinExp *e) { @@ -4829,8 +4845,9 @@ class Interpreter : public Visitor Expression *agg1 = getAggregateFromPointer(p1, &ofs1); Expression *agg2 = getAggregateFromPointer(p2, &ofs2); - if ( !pointToSameMemoryBlock(agg1, agg2) - && agg1->op != TOKnull && agg2->op != TOKnull) + if (!pointToSameMemoryBlock(agg1, agg2) && + agg1->op != TOKnull && + agg2->op != TOKnull) { // Here it is either CANT_INTERPRET, // or an IsInside comparison returning false. @@ -4871,11 +4888,10 @@ class Interpreter : public Visitor // p1 > p2 && p3 > p4 (same direction, also for < && <) // p1 > p2 && p3 < p4 (different direction, also < && >) // Changing any > into >= doesnt affect the result - if ( (dir1 == dir2 && pointToSameMemoryBlock(agg1, agg4) - && pointToSameMemoryBlock(agg2, agg3)) - || (dir1 != dir2 && pointToSameMemoryBlock(agg1, agg3) - && pointToSameMemoryBlock(agg2, agg4)) ) - { // it's a legal two-sided comparison + if ((dir1 == dir2 && pointToSameMemoryBlock(agg1, agg4) && pointToSameMemoryBlock(agg2, agg3)) || + (dir1 != dir2 && pointToSameMemoryBlock(agg1, agg3) && pointToSameMemoryBlock(agg2, agg4))) + { + // it's a legal two-sided comparison result = new IntegerExp(e->loc, (e->op == TOKandand) ? 0 : 1, e->type); return; } @@ -5092,10 +5108,10 @@ class Interpreter : public Visitor if (ecall->op == TOKstar) { // Calling a function pointer - Expression * pe = ((PtrExp*)ecall)->e1; + Expression * pe = ((PtrExp *)ecall)->e1; if (pe->op == TOKvar) { - VarDeclaration *vd = ((VarExp *)((PtrExp*)ecall)->e1)->var->isVarDeclaration(); + VarDeclaration *vd = ((VarExp *)((PtrExp *)ecall)->e1)->var->isVarDeclaration(); if (vd && hasValue(vd) && getValue(vd)->op == TOKsymoff) fd = ((SymOffExp *)getValue(vd))->var->isFuncDeclaration(); else @@ -5114,7 +5130,7 @@ class Interpreter : public Visitor else if (pe->op == TOKsymoff) fd = ((SymOffExp *)pe)->var->isFuncDeclaration(); else - ecall = ((PtrExp*)ecall)->e1->interpret(istate); + ecall = ((PtrExp *)ecall)->e1->interpret(istate); } if (exceptionOrCantInterpret(ecall)) @@ -5133,7 +5149,7 @@ class Interpreter : public Visitor } } - if (ecall->op == TOKdotvar && !((DotVarExp*)ecall)->var->isFuncDeclaration()) + if (ecall->op == TOKdotvar && !((DotVarExp *)ecall)->var->isFuncDeclaration()) { ecall = e->e1->interpret(istate); if (exceptionOrCantInterpret(ecall)) @@ -5146,8 +5162,8 @@ class Interpreter : public Visitor if (ecall->op == TOKdotvar) { // Calling a member function - pthis = ((DotVarExp*)e->e1)->e1; - fd = ((DotVarExp*)e->e1)->var->isFuncDeclaration(); + pthis = ((DotVarExp *)e->e1)->e1; + fd = ((DotVarExp *)e->e1)->var->isFuncDeclaration(); } else if (ecall->op == TOKvar) { @@ -5166,12 +5182,12 @@ class Interpreter : public Visitor else if (ecall->op == TOKfunction) { // Calling a delegate literal - fd = ((FuncExp*)ecall)->fd; + fd = ((FuncExp *)ecall)->fd; } - else if (ecall->op == TOKstar && ((PtrExp*)ecall)->e1->op == TOKfunction) + else if (ecall->op == TOKstar && ((PtrExp *)ecall)->e1->op == TOKfunction) { // Calling a function literal - fd = ((FuncExp*)((PtrExp*)ecall)->e1)->fd; + fd = ((FuncExp *)((PtrExp*)ecall)->e1)->fd; } else if (ecall->op == TOKdelegatefuncptr) { @@ -5330,11 +5346,11 @@ class Interpreter : public Visitor // If the comma returns a temporary variable, it needs to be an lvalue // (this is particularly important for struct constructors) - if (e->e1->op == TOKdeclaration && e->e2->op == TOKvar - && ((DeclarationExp *)e->e1)->declaration == ((VarExp*)e->e2)->var - && ((VarExp*)e->e2)->var->storage_class & STCctfe) // same as Expression::isTemp + if (e->e1->op == TOKdeclaration && e->e2->op == TOKvar && + ((DeclarationExp *)e->e1)->declaration == ((VarExp*)e->e2)->var && + ((VarExp*)e->e2)->var->storage_class & STCctfe) // same as Expression::isTemp { - VarExp* ve = (VarExp *)e->e2; + VarExp *ve = (VarExp *)e->e2; VarDeclaration *v = ve->var->isVarDeclaration(); ctfeStack.push(v); if (!v->init && !getValue(v)) @@ -5418,8 +5434,8 @@ class Interpreter : public Visitor result = e1; return; } - if (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKslice - || e1->op == TOKassocarrayliteral || e1->op == TOKnull) + if (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKslice || + e1->op == TOKassocarrayliteral || e1->op == TOKnull) { result = new IntegerExp(e->loc, resolveArrayLength(e1), e->type); } @@ -5565,8 +5581,8 @@ class Interpreter : public Visitor /* Set the $ variable. * Note that foreach uses indexing but doesn't need $ */ - if (e->lengthVar && (e1->op == TOKstring || e1->op == TOKarrayliteral - || e1->op == TOKslice)) + if (e->lengthVar && + (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKslice)) { uinteger_t dollar = resolveArrayLength(e1); Expression *dollarExp = new IntegerExp(e->loc, dollar, Type::tsize_t); @@ -5599,11 +5615,13 @@ class Interpreter : public Visitor e1 = ((SliceExp *)e1)->e1; e2 = new IntegerExp(e2->loc, indx, e2->type); } - if ((goal == ctfeNeedLvalue && e->type->ty != Taarray && e->type->ty != Tarray - && e->type->ty != Tsarray && e->type->ty != Tstruct && e->type->ty != Tclass) - || (goal == ctfeNeedLvalueRef && e->type->ty != Tsarray && e->type->ty != Tstruct) - ) - { // Pointer or reference of a scalar type + if ((goal == ctfeNeedLvalue && e->type->ty != Taarray && + e->type->ty != Tarray && e->type->ty != Tsarray && + e->type->ty != Tstruct && e->type->ty != Tclass) || + (goal == ctfeNeedLvalueRef && + e->type->ty != Tsarray && e->type->ty != Tstruct)) + { + // Pointer or reference of a scalar type result = new IndexExp(e->loc, e1, e2); result->type = e->type; return; @@ -5827,13 +5845,11 @@ class Interpreter : public Visitor result->type = e->type; return; } - if (e1->op == TOKarrayliteral - || e1->op == TOKstring) + if (e1->op == TOKarrayliteral || e1->op == TOKstring) { - if (iupr < ilwr || iupr > dollar) + if (iupr < ilwr || dollar < iupr) { - e->error("slice [%lld..%lld] exceeds array bounds [0..%lld]", - ilwr, iupr, dollar); + e->error("slice [%lld..%lld] exceeds array bounds [0..%lld]", ilwr, iupr, dollar); result = EXP_CANT_INTERPRET; return; } @@ -5969,8 +5985,8 @@ class Interpreter : public Visitor ultimatePointee = ultimatePointee->nextOf(); ultimateSrc = ultimateSrc->nextOf(); } - if (ultimatePointee->ty != Tvoid && ultimateSrc->ty != Tvoid - && !isSafePointerCast(elemtype, pointee)) + if (ultimatePointee->ty != Tvoid && ultimateSrc->ty != Tvoid && + !isSafePointerCast(elemtype, pointee)) { e->error("reinterpreting cast from %s* to %s* is not supported in CTFE", elemtype->toChars(), pointee->toChars()); @@ -5983,7 +5999,7 @@ class Interpreter : public Visitor if (e1->op == TOKslice) { - if ( ((SliceExp *)e1)->e1->op == TOKnull) + if (((SliceExp *)e1)->e1->op == TOKnull) { result = paintTypeOntoLiteral(e->type, ((SliceExp *)e1)->e1); return; @@ -6094,7 +6110,7 @@ class Interpreter : public Visitor // types of identical size. if ((e->to->ty == Tsarray || e->to->ty == Tarray) && (e1->type->ty == Tsarray || e1->type->ty == Tarray) && - !isSafePointerCast(e1->type->nextOf(), e->to->nextOf()) ) + !isSafePointerCast(e1->type->nextOf(), e->to->nextOf())) { e->error("array cast from %s to %s is not supported at compile time", e1->type->toChars(), e->to->toChars()); result = EXP_CANT_INTERPRET; @@ -6155,15 +6171,14 @@ class Interpreter : public Visitor #endif // Check for int<->float and long<->double casts. - if ( e->e1->op == TOKsymoff && ((SymOffExp *)e->e1)->offset == 0 - && isFloatIntPaint(e->type, ((SymOffExp *)e->e1)->var->type) ) + if (e->e1->op == TOKsymoff && ((SymOffExp *)e->e1)->offset == 0 && + isFloatIntPaint(e->type, ((SymOffExp *)e->e1)->var->type)) { // *(cast(int*)&v, where v is a float variable - result = paintFloatInt(getVarExp(e->loc, istate, ((SymOffExp *)e->e1)->var, ctfeNeedRvalue), - e->type); + result = paintFloatInt(getVarExp(e->loc, istate, ((SymOffExp *)e->e1)->var, ctfeNeedRvalue), e->type); return; } - else if (e->e1->op == TOKcast && ((CastExp *)e->e1)->e1->op == TOKaddress) + if (e->e1->op == TOKcast && ((CastExp *)e->e1)->e1->op == TOKaddress) { // *(cast(int *))&x where x is a float expression Expression *x = ((AddrExp *)(((CastExp *)e->e1)->e1))->e1; @@ -6181,8 +6196,7 @@ class Interpreter : public Visitor if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64) { AddrExp *ade = (AddrExp *)ae->e1; - Expression *ex = ade->e1; - ex = ex->interpret(istate); + Expression *ex = ade->e1->interpret(istate); if (exceptionOrCantInterpret(ex)) { result = ex; @@ -6238,8 +6252,11 @@ class Interpreter : public Visitor if (exceptionOrCantInterpret(result)) return; - if (!(result->op == TOKvar || result->op == TOKdotvar || result->op == TOKindex - || result->op == TOKslice || result->op == TOKaddress)) + if (!(result->op == TOKvar || + result->op == TOKdotvar || + result->op == TOKindex || + result->op == TOKslice || + result->op == TOKaddress)) { if (result->op == TOKsymoff) e->error("cannot dereference pointer to static variable %s at compile time", ((SymOffExp *)result)->var->toChars()); @@ -6257,14 +6274,14 @@ class Interpreter : public Visitor // If the index has the same levels of indirection, it's an index int srcLevels = 0; int destLevels = 0; - for(Type *xx = ie->e1->type; xx->ty == Tpointer; xx = xx->nextOf()) + for (Type *xx = ie->e1->type; xx->ty == Tpointer; xx = xx->nextOf()) ++srcLevels; - for(Type *xx = result->type->nextOf(); xx->ty == Tpointer; xx = xx->nextOf()) + for (Type *xx = result->type->nextOf(); xx->ty == Tpointer; xx = xx->nextOf()) ++destLevels; bool isGenuineIndex = (srcLevels == destLevels); - if ((ie->e1->op == TOKarrayliteral || ie->e1->op == TOKstring) - && ie->e2->op == TOKint64) + if ((ie->e1->op == TOKarrayliteral || ie->e1->op == TOKstring) && + ie->e2->op == TOKint64) { Expression *dollar = ArrayLength(Type::tsize_t, ie->e1); dinteger_t len = dollar->toInteger(); @@ -6415,14 +6432,17 @@ class Interpreter : public Visitor result->op == TOKarrayliteral || result->op == TOKassocarrayliteral || result->op == TOKstring || result->op == TOKclassreference || result->op == TOKslice)) + { return; + } /* Element is an allocated pointer, which was created in * CastExp. */ if (goal == ctfeNeedLvalue && result->op == TOKindex && - result->type->equals(e->type) && - isPointer(e->type) ) + result->type->equals(e->type) && isPointer(e->type)) + { return; + } // ...Otherwise, just return the (simplified) dotvar expression result = new DotVarExp(e->loc, ex, v); result->type = e->type; @@ -6663,8 +6683,7 @@ bool scrubArray(Loc loc, Expressions *elems, bool structlit) if (structlit && ((m->op == TOKvoid) || (m->op == TOKarrayliteral && m->type->ty == Tsarray && isEntirelyVoid(((ArrayLiteralExp *)m)->elements)) || - (m->op == TOKstructliteral && isEntirelyVoid(((StructLiteralExp *)m)->elements))) - ) + (m->op == TOKstructliteral && isEntirelyVoid(((StructLiteralExp *)m)->elements)))) { m = NULL; } @@ -6739,7 +6758,8 @@ Expression *interpret_values(InterState *istate, Expression *earg, Type *returnT // signature is int delegate(ref Value) OR int delegate(ref Key, ref Value) Expression *interpret_aaApply(InterState *istate, Expression *aa, Expression *deleg) -{ aa = aa->interpret(istate); +{ + aa = aa->interpret(istate); if (exceptionOrCantInterpret(aa)) return aa; if (aa->op != TOKassocarrayliteral) @@ -6776,7 +6796,8 @@ Expression *interpret_aaApply(InterState *istate, Expression *aa, Expression *de Expression *ekey = (*ae->keys)[i]; Expression *evalue = (*ae->values)[i]; if (wantRefValue) - { Type *t = evalue->type; + { + Type *t = evalue->type; evalue = new IndexExp(deleg->loc, ae, ekey); evalue->type = t; } @@ -6842,7 +6863,8 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del else if (str->op == TOKarrayliteral) ale = (ArrayLiteralExp *)str; else - { str->error("CTFE internal error: cannot foreach %s", str->toChars()); + { + str->error("CTFE internal error: cannot foreach %s", str->toChars()); return EXP_CANT_INTERPRET; } Expressions args; @@ -6865,16 +6887,18 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del size_t currentIndex = indx; // The index of the decoded character if (ale) - { // If it is an array literal, copy the code points into the buffer + { + // If it is an array literal, copy the code points into the buffer size_t buflen = 1; // #code points in the buffer size_t n = 1; // #code points in this char size_t sz = (size_t)ale->type->nextOf()->size(); - switch(sz) + switch (sz) { case 1: if (rvs) - { // find the start of the string + { + // find the start of the string --indx; buflen = 1; while (indx > 0 && buflen < 4) @@ -6882,7 +6906,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del Expression * r = (*ale->elements)[indx]; assert(r->op == TOKint64); utf8_t x = (utf8_t)(((IntegerExp *)r)->getInteger()); - if ( (x & 0xC0) != 0x80) + if ((x & 0xC0) != 0x80) break; ++buflen; } @@ -6900,7 +6924,8 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del break; case 2: if (rvs) - { // find the start of the string + { + // find the start of the string --indx; buflen = 1; Expression * r = (*ale->elements)[indx]; @@ -6941,14 +6966,16 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del indx += n; } else - { // String literals + { + // String literals size_t saveindx; // used for reverse iteration switch (se->sz) { case 1: if (rvs) - { // find the start of the string + { + // find the start of the string utf8_t *s = (utf8_t *)se->string; --indx; while (indx > 0 && ((s[indx]&0xC0) == 0x80)) @@ -6961,7 +6988,8 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del break; case 2: if (rvs) - { // find the start + { + // find the start unsigned short *s = (unsigned short *)se->string; --indx; if (s[indx] >= 0xDC00 && s[indx]<= 0xDFFF) @@ -6984,14 +7012,15 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del } } if (errmsg) - { deleg->error("%s", errmsg); + { + deleg->error("%s", errmsg); return EXP_CANT_INTERPRET; } // Step 2: encode the dchar in the target encoding int charlen = 1; // How many codepoints are involved? - switch(charType->size()) + switch (charType->size()) { case 1: charlen = utf_codeLengthChar(rawvalue); @@ -7020,7 +7049,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del for (int k= 0; k < charlen; ++k) { dchar_t codepoint; - switch(charType->size()) + switch (charType->size()) { case 1: codepoint = utf8buf[k]; @@ -7060,7 +7089,8 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc, if (!pthis) { if (isBuiltin(fd) == BUILTINyes) - { Expressions args; + { + Expressions args; args.setDim(nargs); for (size_t i = 0; i < args.dim; i++) { @@ -7101,7 +7131,8 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc, if (pthis && !fd->fbody && fd->isCtorDeclaration() && fd->parent && fd->parent->parent && fd->parent->parent->ident == Id::object) { if (pthis->op == TOKclassreference && fd->parent->ident == Id::Throwable) - { // At present, the constructors just copy their arguments into the struct. + { + // At present, the constructors just copy their arguments into the struct. // But we might need some magic if stack tracing gets added to druntime. StructLiteralExp *se = ((ClassReferenceExp *)pthis)->value; assert(arguments->dim <= se->elements->dim); @@ -7117,24 +7148,27 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc, } if (nargs == 1 && !pthis && (fd->ident == Id::criticalenter || fd->ident == Id::criticalexit)) - { // Support synchronized{} as a no-op + { + // Support synchronized{} as a no-op return EXP_VOID_INTERPRET; } if (!pthis) { size_t idlen = strlen(fd->ident->string); - if (nargs == 2 && (idlen == 10 || idlen == 11) - && !strncmp(fd->ident->string, "_aApply", 7)) - { // Functions from aApply.d and aApplyR.d in the runtime + if (nargs == 2 && (idlen == 10 || idlen == 11) && + !strncmp(fd->ident->string, "_aApply", 7)) + { + // Functions from aApply.d and aApplyR.d in the runtime bool rvs = (idlen == 11); // true if foreach_reverse char c = fd->ident->string[idlen-3]; // char width: 'c', 'w', or 'd' char s = fd->ident->string[idlen-2]; // string width: 'c', 'w', or 'd' char n = fd->ident->string[idlen-1]; // numParams: 1 or 2. // There are 12 combinations - if ( (n == '1' || n == '2') && - (c == 'c' || c == 'w' || c == 'd') && - (s == 'c' || s == 'w' || s == 'd') && c != s) - { Expression *str = (*arguments)[0]; + if ((n == '1' || n == '2') && + (c == 'c' || c == 'w' || c == 'd') && + (s == 'c' || s == 'w' || s == 'd') && c != s) + { + Expression *str = (*arguments)[0]; str = str->interpret(istate); if (exceptionOrCantInterpret(str)) return str;