Commit 208ed40a by Ben Clayton

Reactor: Add Traits for Reference types

ReactorType<Reference<T>> will now resolve to T. This also enables support of ValueOf(ReactorType<Reference<T>>). Required for Coroutines. Bug: b/131672705 Change-Id: Icbc95488f5299b8d70e72142e44af9ed1af598d1 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30569Tested-by: 's avatarBen Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 4b944653
...@@ -161,6 +161,8 @@ namespace rr ...@@ -161,6 +161,8 @@ namespace rr
class Reference class Reference
{ {
public: public:
using reference_underlying_type = T;
explicit Reference(Value *pointer, int alignment = 1); explicit Reference(Value *pointer, int alignment = 1);
RValue<T> operator=(RValue<T> rhs) const; RValue<T> operator=(RValue<T> rhs) const;
...@@ -2402,7 +2404,8 @@ namespace rr ...@@ -2402,7 +2404,8 @@ namespace rr
void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB); void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB);
// ValueOf returns a rr::Value* for the given C-type, RValue<T>, or LValue<T>. // ValueOf returns a rr::Value* for the given C-type, RValue<T>, LValue<T>
// or Reference<T>.
template <typename T> template <typename T>
inline Value* ValueOf(const T &v) inline Value* ValueOf(const T &v)
{ {
......
...@@ -1434,6 +1434,17 @@ static_assert(IsLValue<Long>::value, ""); ...@@ -1434,6 +1434,17 @@ static_assert(IsLValue<Long>::value, "");
static_assert(IsLValue<UInt>::value, ""); static_assert(IsLValue<UInt>::value, "");
static_assert(IsLValue<Float>::value, ""); static_assert(IsLValue<Float>::value, "");
// Assert IsReference<> resolves true for Reference types.
static_assert(IsReference<Reference<Bool>>::value, "");
static_assert(IsReference<Reference<Byte>>::value, "");
static_assert(IsReference<Reference<SByte>>::value, "");
static_assert(IsReference<Reference<Short>>::value, "");
static_assert(IsReference<Reference<UShort>>::value, "");
static_assert(IsReference<Reference<Int>>::value, "");
static_assert(IsReference<Reference<Long>>::value, "");
static_assert(IsReference<Reference<UInt>>::value, "");
static_assert(IsReference<Reference<Float>>::value, "");
// Assert IsRValue<> resolves false for LValue types. // Assert IsRValue<> resolves false for LValue types.
static_assert(!IsRValue<Void>::value, ""); static_assert(!IsRValue<Void>::value, "");
static_assert(!IsRValue<Bool>::value, ""); static_assert(!IsRValue<Bool>::value, "");
...@@ -1446,6 +1457,18 @@ static_assert(!IsRValue<Long>::value, ""); ...@@ -1446,6 +1457,18 @@ static_assert(!IsRValue<Long>::value, "");
static_assert(!IsRValue<UInt>::value, ""); static_assert(!IsRValue<UInt>::value, "");
static_assert(!IsRValue<Float>::value, ""); static_assert(!IsRValue<Float>::value, "");
// Assert IsRValue<> resolves false for Reference types.
static_assert(!IsRValue<Reference<Void>>::value, "");
static_assert(!IsRValue<Reference<Bool>>::value, "");
static_assert(!IsRValue<Reference<Byte>>::value, "");
static_assert(!IsRValue<Reference<SByte>>::value, "");
static_assert(!IsRValue<Reference<Short>>::value, "");
static_assert(!IsRValue<Reference<UShort>>::value, "");
static_assert(!IsRValue<Reference<Int>>::value, "");
static_assert(!IsRValue<Reference<Long>>::value, "");
static_assert(!IsRValue<Reference<UInt>>::value, "");
static_assert(!IsRValue<Reference<Float>>::value, "");
// Assert IsRValue<> resolves false for C types. // Assert IsRValue<> resolves false for C types.
static_assert(!IsRValue<void>::value, ""); static_assert(!IsRValue<void>::value, "");
static_assert(!IsRValue<bool>::value, ""); static_assert(!IsRValue<bool>::value, "");
...@@ -1473,6 +1496,18 @@ static_assert(!IsLValue<RValue<Float>>::value, ""); ...@@ -1473,6 +1496,18 @@ static_assert(!IsLValue<RValue<Float>>::value, "");
// Assert IsLValue<> resolves false for Void type. // Assert IsLValue<> resolves false for Void type.
static_assert(!IsLValue<Void>::value, ""); static_assert(!IsLValue<Void>::value, "");
// Assert IsLValue<> resolves false for Reference<> types.
static_assert(!IsLValue<Reference<Void>>::value, "");
static_assert(!IsLValue<Reference<Bool>>::value, "");
static_assert(!IsLValue<Reference<Byte>>::value, "");
static_assert(!IsLValue<Reference<SByte>>::value, "");
static_assert(!IsLValue<Reference<Short>>::value, "");
static_assert(!IsLValue<Reference<UShort>>::value, "");
static_assert(!IsLValue<Reference<Int>>::value, "");
static_assert(!IsLValue<Reference<Long>>::value, "");
static_assert(!IsLValue<Reference<UInt>>::value, "");
static_assert(!IsLValue<Reference<Float>>::value, "");
// Assert IsLValue<> resolves false for C types. // Assert IsLValue<> resolves false for C types.
static_assert(!IsLValue<void>::value, ""); static_assert(!IsLValue<void>::value, "");
static_assert(!IsLValue<bool>::value, ""); static_assert(!IsLValue<bool>::value, "");
...@@ -1509,6 +1544,17 @@ static_assert(IsDefined<Long>::value, ""); ...@@ -1509,6 +1544,17 @@ static_assert(IsDefined<Long>::value, "");
static_assert(IsDefined<UInt>::value, ""); static_assert(IsDefined<UInt>::value, "");
static_assert(IsDefined<Float>::value, ""); static_assert(IsDefined<Float>::value, "");
// Assert IsDefined<> resolves true for Reference<> types.
static_assert(IsDefined<Reference<Bool>>::value, "");
static_assert(IsDefined<Reference<Byte>>::value, "");
static_assert(IsDefined<Reference<SByte>>::value, "");
static_assert(IsDefined<Reference<Short>>::value, "");
static_assert(IsDefined<Reference<UShort>>::value, "");
static_assert(IsDefined<Reference<Int>>::value, "");
static_assert(IsDefined<Reference<Long>>::value, "");
static_assert(IsDefined<Reference<UInt>>::value, "");
static_assert(IsDefined<Reference<Float>>::value, "");
// Assert IsDefined<> resolves true for C types. // Assert IsDefined<> resolves true for C types.
static_assert(IsDefined<void>::value, ""); static_assert(IsDefined<void>::value, "");
static_assert(IsDefined<bool>::value, ""); static_assert(IsDefined<bool>::value, "");
......
...@@ -121,6 +121,10 @@ namespace rr ...@@ -121,6 +121,10 @@ namespace rr
// IsLValue::value is true if T is of, or derives from type LValue<T>. // IsLValue::value is true if T is of, or derives from type LValue<T>.
template <typename T> struct IsLValue { static constexpr bool value = std::is_base_of<LValue<T>, T>::value; }; template <typename T> struct IsLValue { static constexpr bool value = std::is_base_of<LValue<T>, T>::value; };
// IsReference::value is true if T is of type Reference<X>, where X is any type.
template <typename T, typename Enable = void> struct IsReference { static constexpr bool value = false; };
template <typename T> struct IsReference<T, typename std::enable_if<IsDefined<typename T::reference_underlying_type>::value>::type> { static constexpr bool value = true; };
// ReactorType<T> returns the LValue Reactor type for T. // ReactorType<T> returns the LValue Reactor type for T.
// T can be a C-type, RValue or LValue. // T can be a C-type, RValue or LValue.
template<typename T, typename ENABLE = void> struct ReactorTypeT; template<typename T, typename ENABLE = void> struct ReactorTypeT;
...@@ -128,6 +132,8 @@ namespace rr ...@@ -128,6 +132,8 @@ namespace rr
template<typename T> struct ReactorTypeT<T, typename std::enable_if<IsDefined<CToReactor<T>>::value>::type> { using type = CToReactor<T>; }; template<typename T> struct ReactorTypeT<T, typename std::enable_if<IsDefined<CToReactor<T>>::value>::type> { using type = CToReactor<T>; };
template<typename T> struct ReactorTypeT<T, typename std::enable_if<IsRValue<T>::value>::type> { using type = typename T::rvalue_underlying_type; }; template<typename T> struct ReactorTypeT<T, typename std::enable_if<IsRValue<T>::value>::type> { using type = typename T::rvalue_underlying_type; };
template<typename T> struct ReactorTypeT<T, typename std::enable_if<IsLValue<T>::value>::type> { using type = T; }; template<typename T> struct ReactorTypeT<T, typename std::enable_if<IsLValue<T>::value>::type> { using type = T; };
template<typename T> struct ReactorTypeT<T, typename std::enable_if<IsReference<T>::value>::type> { using type = T; };
// Reactor types that can be used as a return type for a function. // Reactor types that can be used as a return type for a function.
template <typename T> struct CanBeUsedAsReturn { static constexpr bool value = false; }; template <typename T> struct CanBeUsedAsReturn { static constexpr bool value = false; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment