forked from OSchip/llvm-project
[clang][Interp] Implement IntegralToBoolean casts
Redo how we do IntegralCasts and implement IntegralToBoolean casts using the already existing cast op. Differential Revision: https://reviews.llvm.org/D132739
This commit is contained in:
parent
8e41e6a4ea
commit
95e6a407d9
|
@ -50,6 +50,7 @@ class Boolean {
|
|||
explicit operator int64_t() const { return V; }
|
||||
explicit operator uint64_t() const { return V; }
|
||||
explicit operator int() const { return V; }
|
||||
explicit operator bool() const { return V; }
|
||||
|
||||
APSInt toAPSInt() const {
|
||||
return APSInt(APInt(1, static_cast<uint64_t>(V), false), true);
|
||||
|
@ -85,9 +86,10 @@ class Boolean {
|
|||
static Boolean min(unsigned NumBits) { return Boolean(false); }
|
||||
static Boolean max(unsigned NumBits) { return Boolean(true); }
|
||||
|
||||
template <typename T>
|
||||
static std::enable_if_t<std::is_integral<T>::value, Boolean> from(T Value) {
|
||||
return Boolean(Value != 0);
|
||||
template <typename T> static Boolean from(T Value) {
|
||||
if constexpr (std::is_integral<T>::value)
|
||||
return Boolean(Value != 0);
|
||||
return Boolean(static_cast<decltype(Boolean::V)>(Value) != 0);
|
||||
}
|
||||
|
||||
template <unsigned SrcBits, bool SrcSign>
|
||||
|
|
|
@ -117,6 +117,7 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
|
|||
case CK_NullToPointer:
|
||||
return this->Visit(SubExpr);
|
||||
|
||||
case CK_IntegralToBoolean:
|
||||
case CK_IntegralCast: {
|
||||
Optional<PrimType> FromT = classify(SubExpr->getType());
|
||||
Optional<PrimType> ToT = classify(CE->getType());
|
||||
|
@ -132,19 +133,6 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
|
|||
case CK_ToVoid:
|
||||
return discard(SubExpr);
|
||||
|
||||
case CK_IntegralToBoolean:
|
||||
// Compare integral from Subexpr with 0
|
||||
if (Optional<PrimType> T = classify(SubExpr->getType())) {
|
||||
if (!this->Visit(SubExpr))
|
||||
return false;
|
||||
|
||||
if (!this->emitConst(SubExpr, 0))
|
||||
return false;
|
||||
|
||||
return this->emitNE(*T, SubExpr);
|
||||
}
|
||||
return false;
|
||||
|
||||
default:
|
||||
assert(false && "Cast not implemented");
|
||||
}
|
||||
|
|
|
@ -425,12 +425,16 @@ def Neg: Opcode {
|
|||
//===----------------------------------------------------------------------===//
|
||||
// TODO: Expand this to handle casts between more types.
|
||||
|
||||
def Sint32TypeClass : TypeClass {
|
||||
let Types = [Sint32];
|
||||
def FromCastTypeClass : TypeClass {
|
||||
let Types = [Uint32, Sint32, Bool];
|
||||
}
|
||||
|
||||
def ToCastTypeClass : TypeClass {
|
||||
let Types = [Uint32, Sint32, Bool];
|
||||
}
|
||||
|
||||
def Cast: Opcode {
|
||||
let Types = [BoolTypeClass, Sint32TypeClass];
|
||||
let Types = [FromCastTypeClass, ToCastTypeClass];
|
||||
let HasGroup = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,37 @@ static_assert(number != 10, ""); // expected-error{{failed}} \
|
|||
// expected-note{{evaluates to}} \
|
||||
// ref-note{{evaluates to}}
|
||||
|
||||
constexpr bool b = number;
|
||||
static_assert(b, "");
|
||||
constexpr int one = true;
|
||||
static_assert(one == 1, "");
|
||||
|
||||
namespace IntegralCasts {
|
||||
constexpr int i = 12;
|
||||
constexpr unsigned int ui = i;
|
||||
static_assert(ui == 12, "");
|
||||
constexpr unsigned int ub = !false;
|
||||
static_assert(ub == 1, "");
|
||||
|
||||
constexpr int si = ui;
|
||||
static_assert(si == 12, "");
|
||||
constexpr int sb = true;
|
||||
static_assert(sb == 1, "");
|
||||
|
||||
constexpr int zero = 0;
|
||||
constexpr unsigned int uzero = 0;
|
||||
constexpr bool bs = i;
|
||||
static_assert(bs, "");
|
||||
constexpr bool bu = ui;
|
||||
static_assert(bu, "");
|
||||
constexpr bool ns = zero;
|
||||
static_assert(!ns, "");
|
||||
constexpr bool nu = uzero;
|
||||
static_assert(!nu, "");
|
||||
};
|
||||
|
||||
|
||||
|
||||
constexpr bool getTrue() { return true; }
|
||||
constexpr bool getFalse() { return false; }
|
||||
constexpr void* getNull() { return nullptr; }
|
||||
|
|
Loading…
Reference in New Issue