diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index ebf362238ba09..45e5b49546270 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -33,9 +33,9 @@ template class Integral; template class IntegralAP final { private: friend IntegralAP; - APSInt V; + APInt V; - template static T truncateCast(const APSInt &V) { + template static T truncateCast(const APInt &V) { constexpr unsigned BitSize = sizeof(T) * 8; if (BitSize >= V.getBitWidth()) return std::is_signed_v ? V.getSExtValue() : V.getZExtValue(); @@ -48,23 +48,37 @@ template class IntegralAP final { using AsUnsigned = IntegralAP; template - IntegralAP(T Value) - : V(APInt(sizeof(T) * 8, static_cast(Value), - std::is_signed_v)) {} + IntegralAP(T Value, unsigned BitWidth) + : V(APInt(BitWidth, static_cast(Value), Signed)) {} IntegralAP(APInt V) : V(V) {} - IntegralAP(APSInt V) : V(V) {} /// Arbitrary value for uninitialized variables. - IntegralAP() : V(APSInt::getMaxValue(1024, Signed)) {} + IntegralAP() : IntegralAP(-1, 1024) {} IntegralAP operator-() const { return IntegralAP(-V); } IntegralAP operator-(const IntegralAP &Other) const { return IntegralAP(V - Other.V); } - bool operator>(IntegralAP RHS) const { return V > RHS.V; } - bool operator>=(IntegralAP RHS) const { return V >= RHS.V; } - bool operator<(IntegralAP RHS) const { return V < RHS.V; } - bool operator<=(IntegralAP RHS) const { return V <= RHS.V; } + bool operator>(const IntegralAP &RHS) const { + if constexpr (Signed) + return V.ugt(RHS.V); + return V.sgt(RHS.V); + } + bool operator>=(IntegralAP RHS) const { + if constexpr (Signed) + return V.uge(RHS.V); + return V.sge(RHS.V); + } + bool operator<(IntegralAP RHS) const { + if constexpr (Signed) + return V.slt(RHS.V); + return V.slt(RHS.V); + } + bool operator<=(IntegralAP RHS) const { + if constexpr (Signed) + return V.ult(RHS.V); + return V.ult(RHS.V); + } explicit operator bool() const { return !V.isZero(); } explicit operator int8_t() const { return truncateCast(V); } @@ -78,42 +92,32 @@ template class IntegralAP final { template static IntegralAP from(T Value, unsigned NumBits = 0) { assert(NumBits > 0); - APSInt Copy = - APSInt(APInt(NumBits, static_cast(Value), Signed), !Signed); + APInt Copy = APInt(NumBits, static_cast(Value), Signed); return IntegralAP(Copy); } template static IntegralAP from(IntegralAP V, unsigned NumBits = 0) { - if constexpr (Signed == InputSigned) - return V; - - APSInt Copy = V.V; - Copy.setIsSigned(Signed); - - return IntegralAP(Copy); + return IntegralAP(V.V); } template static IntegralAP from(Integral I, unsigned BitWidth) { - APSInt Copy = - APSInt(APInt(BitWidth, static_cast(I), InputSigned), !Signed); - Copy.setIsSigned(Signed); + APInt Copy = APInt(BitWidth, static_cast(I), InputSigned); - assert(Copy.isSigned() == Signed); return IntegralAP(Copy); } static IntegralAP zero(int32_t BitWidth) { - APSInt V = APSInt(APInt(BitWidth, 0LL, Signed), !Signed); + APInt V = APInt(BitWidth, 0LL, Signed); return IntegralAP(V); } constexpr unsigned bitWidth() const { return V.getBitWidth(); } - APSInt toAPSInt(unsigned Bits = 0) const { return V; } - APValue toAPValue() const { return APValue(V); } + APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, Signed); } + APValue toAPValue() const { return APValue(APSInt(V, Signed)); } bool isZero() const { return V.isZero(); } bool isPositive() const { return V.isNonNegative(); } @@ -139,22 +143,38 @@ template class IntegralAP final { } IntegralAP toUnsigned() const { - APSInt Copy = V; - Copy.setIsSigned(false); + APInt Copy = V; return IntegralAP(Copy); } ComparisonCategoryResult compare(const IntegralAP &RHS) const { - return Compare(V, RHS.V); + assert(Signed == RHS.isSigned()); + assert(bitWidth() == RHS.bitWidth()); + if constexpr (Signed) { + if (V.slt(RHS.V)) + return ComparisonCategoryResult::Less; + if (V.sgt(RHS.V)) + return ComparisonCategoryResult::Greater; + return ComparisonCategoryResult::Equal; + } + + assert(!Signed); + if (V.ult(RHS.V)) + return ComparisonCategoryResult::Less; + if (V.ugt(RHS.V)) + return ComparisonCategoryResult::Greater; + return ComparisonCategoryResult::Equal; } static bool increment(IntegralAP A, IntegralAP *R) { + // FIXME: Implement. assert(false); - *R = IntegralAP(A.V + 1); + *R = IntegralAP(A.V - 1); return false; } static bool decrement(IntegralAP A, IntegralAP *R) { + // FIXME: Implement. assert(false); *R = IntegralAP(A.V - 1); return false; @@ -170,48 +190,46 @@ template class IntegralAP final { } static bool mul(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { + // FIXME: Implement. assert(false); - // return CheckMulUB(A.V, B.V, R->V); return false; } static bool rem(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { + // FIXME: Implement. assert(false); - *R = IntegralAP(A.V % B.V); return false; } static bool div(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { + // FIXME: Implement. assert(false); - *R = IntegralAP(A.V / B.V); return false; } static bool bitAnd(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { + // FIXME: Implement. assert(false); - *R = IntegralAP(A.V & B.V); return false; } static bool bitOr(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { assert(false); - *R = IntegralAP(A.V | B.V); return false; } static bool bitXor(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { + // FIXME: Implement. assert(false); - *R = IntegralAP(A.V ^ B.V); return false; } static bool neg(const IntegralAP &A, IntegralAP *R) { - APSInt AI = A.V; - - AI.setIsSigned(Signed); + APInt AI = A.V; + AI.negate(); *R = IntegralAP(AI); return false; } @@ -223,12 +241,12 @@ template class IntegralAP final { static void shiftLeft(const IntegralAP A, const IntegralAP B, unsigned OpBits, IntegralAP *R) { - *R = IntegralAP(A.V << B.V.getZExtValue()); + *R = IntegralAP(A.V.shl(B.V.getZExtValue())); } static void shiftRight(const IntegralAP A, const IntegralAP B, unsigned OpBits, IntegralAP *R) { - *R = IntegralAP(A.V >> B.V.getZExtValue()); + *R = IntegralAP(A.V.ashr(B.V.getZExtValue())); } private: @@ -239,8 +257,8 @@ template class IntegralAP final { return false; } - const APSInt &LHS = A.V; - const APSInt &RHS = B.V; + const APSInt &LHS = APSInt(A.V, A.isSigned()); + const APSInt &RHS = APSInt(B.V, B.isSigned()); APSInt Value(LHS.extend(BitWidth) + RHS.extend(BitWidth), false); APSInt Result = Value.trunc(LHS.getBitWidth());