Reactor: Change the signature of PrintValue::Ty So that the print value's 'fmt' is a dynamic function instead of a constexpr. Let's us do smarter stuff based on the type and value, and will allow us to move functionality from overloads on rr::PrintValue to PrintValue::Ty template specializations. Also fix a bunch of missing integer expansion casts which were missing from ca8e3d7c. Bug: b/140287657 Change-Id: I7e18c35ae23d8a2dd6b726562ae1348a1b7075dd Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/32049 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Tested-by: Ben Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp index 756fae6..8b2716d 100644 --- a/src/Reactor/Reactor.hpp +++ b/src/Reactor/Reactor.hpp
@@ -3295,29 +3295,16 @@ { // Ty is a template that can be specialized for printing type T. // Each specialization must expose: - // * A 'static constexpr const char* fmt' field that provides the + // * A 'static std::string fmt(const T& v)' method that provides the // printf format specifier. // * A 'static std::vector<rr::Value*> val(const T& v)' method that // returns all the printf format values. template <typename T> struct Ty { - // static constexpr const char* fmt; - // static std::vector<rr::Value*> val(const T& v) + // static std::string fmt(const T& v); + // static std::vector<rr::Value*> val(const T& v); }; - // returns the printf value(s) for the given LValue. - template <typename T> - static std::vector<Value*> val(const LValue<T>& v) { return val(RValue<T>(v.loadValue())); } - - // returns the printf value(s) for the given RValue. - template <typename T> - static std::vector<Value*> val(const RValue<T>& v) { return Ty<T>::val(v); } - - // returns the printf value from for the given type with a - // PrintValue::Ty<T> specialization. - template <typename T> - static std::vector<Value*> val(const T& v) { return Ty<T>::val(v); } - // returns the printf values for all the values in the given array. template <typename T> static std::vector<Value*> val(const T* list, int count) { @@ -3331,15 +3318,16 @@ return values; } - // fmt returns a comma-delimited list of the string el repeated count - // times enclosed in square brackets. - static std::string fmt(const char* el, int count) + // fmt returns the comma-delimited list of printf format strings for + // every element in the provided list, all enclosed in square brackets. + template <typename T> + static std::string fmt(const T* list, int count) { std::string out = "["; for (int i = 0; i < count; i++) { if (i > 0) { out += ", "; } - out += el; + out += fmt(list[i]); } return out + "]"; } @@ -3357,16 +3345,16 @@ // Constructs a PrintValue for the given value. template <typename T> - PrintValue(const T& v) : format(Ty<T>::fmt), values(val(v)) {} + PrintValue(const T& v) : format(fmt(v)), values(val(v)) {} // Constructs a PrintValue for the given static array. template <typename T, int N> - PrintValue(const T (&v)[N]) : format(fmt(Ty<T>::fmt, N)), values(val(&v[0], N)) {} + PrintValue(const T (&v)[N]) : format(fmt(&v[0], N)), values(val(&v[0], N)) {} // Constructs a PrintValue for the given array starting at arr of length // len. template <typename T> - PrintValue(const T* arr, int len) : format(fmt(Ty<T>::fmt, len)), values(val(arr, len)) {} + PrintValue(const T* arr, int len) : format(fmt(arr, len)), values(val(arr, len)) {} // PrintValue constructors for plain-old-data values. PrintValue(bool v) : format(v ? "true" : "false") {} @@ -3397,11 +3385,13 @@ // { // template <> struct PrintValue::Ty<Mat4x4> // { - // static constexpr const char* fmt = - // "[a: <%f, %f, %f, %f>," - // " b: <%f, %f, %f, %f>," - // " c: <%f, %f, %f, %f>," - // " d: <%f, %f, %f, %f>]"; + // static std::string fmt(const Mat4x4& v) + // { + // return "[a: <%f, %f, %f, %f>," + // " b: <%f, %f, %f, %f>," + // " c: <%f, %f, %f, %f>," + // " d: <%f, %f, %f, %f>]"; + // } // static std::vector<rr::Value*> val(const Mat4x4& v) // { // return PrintValue::vals(v.a, v.b, v.c, v.d); @@ -3419,114 +3409,124 @@ } return joined; } + + // returns the printf format specifier for the given type via the + // PrintValue::Ty<T> specialization. + template <typename T> + static std::string fmt(const T& v) { return Ty<T>::fmt(v); } + + // returns the printf value for the given type with a + // PrintValue::Ty<T> specialization. + template <typename T> + static std::vector<Value*> val(const T& v) { return Ty<T>::val(v); } }; // PrintValue::Ty<T> specializations for basic types. template <> struct PrintValue::Ty<const char*> { - static constexpr const char* fmt = "%s"; + static std::string fmt(const char* v) { return "%s"; } static std::vector<Value*> val(const char* v); }; template <> struct PrintValue::Ty<std::string> { - static constexpr const char* fmt = PrintValue::Ty<const char*>::fmt; + static std::string fmt(const std::string& v) { return PrintValue::Ty<const char*>::fmt(v.c_str()); } static std::vector<Value*> val(const std::string& v) { return PrintValue::Ty<const char*>::val(v.c_str()); } }; // PrintValue::Ty<T> specializations for standard Reactor types. template <> struct PrintValue::Ty<Bool> { - static constexpr const char* fmt = "%d"; + static std::string fmt(const RValue<Bool>& v) { return "%d"; } static std::vector<Value*> val(const RValue<Bool>& v) { return {v.value}; } }; template <> struct PrintValue::Ty<Byte> { - static constexpr const char* fmt = "%d"; - static std::vector<Value*> val(const RValue<Byte>& v) { return {v.value}; } + static std::string fmt(const RValue<Byte>& v) { return "%d"; } + static std::vector<Value*> val(const RValue<Byte>& v); }; template <> struct PrintValue::Ty<Byte4> { - static constexpr const char* fmt = "[%d, %d, %d, %d]"; + static std::string fmt(const RValue<Byte4>& v) { return "[%d, %d, %d, %d]"; } static std::vector<Value*> val(const RValue<Byte4>& v); }; template <> struct PrintValue::Ty<Int> { - static constexpr const char* fmt = "%d"; + static std::string fmt(const RValue<Int>& v) { return "%d"; } static std::vector<Value*> val(const RValue<Int>& v); }; template <> struct PrintValue::Ty<Int2> { - static constexpr const char* fmt = "[%d, %d]"; + static std::string fmt(const RValue<Int>& v) { return "[%d, %d]"; } static std::vector<Value*> val(const RValue<Int2>& v); }; template <> struct PrintValue::Ty<Int4> { - static constexpr const char* fmt = "[%d, %d, %d, %d]"; + static std::string fmt(const RValue<Int4>& v) { return "[%d, %d, %d, %d]"; } static std::vector<Value*> val(const RValue<Int4>& v); }; template <> struct PrintValue::Ty<UInt> { - static constexpr const char* fmt = "%u"; + static std::string fmt(const RValue<UInt>& v) { return "%u"; } static std::vector<Value*> val(const RValue<UInt>& v); }; template <> struct PrintValue::Ty<UInt2> { - static constexpr const char* fmt = "[%u, %u]"; + static std::string fmt(const RValue<UInt>& v) { return "[%u, %u]"; } static std::vector<Value*> val(const RValue<UInt2>& v); }; template <> struct PrintValue::Ty<UInt4> { - static constexpr const char* fmt = "[%u, %u, %u, %u]"; + static std::string fmt(const RValue<UInt4>& v) { return "[%u, %u, %u, %u]"; } static std::vector<Value*> val(const RValue<UInt4>& v); }; template <> struct PrintValue::Ty<Short> { - static constexpr const char* fmt = "%d"; - static std::vector<Value*> val(const RValue<Short>& v) { return {v.value}; } + static std::string fmt(const RValue<Short>& v) { return "%d"; } + static std::vector<Value*> val(const RValue<Short>& v); }; template <> struct PrintValue::Ty<Short4> { - static constexpr const char* fmt = "[%d, %d, %d, %d]"; + static std::string fmt(const RValue<Short4>& v) { return "[%d, %d, %d, %d]"; } static std::vector<Value*> val(const RValue<Short4>& v); }; template <> struct PrintValue::Ty<UShort> { - static constexpr const char* fmt = "%u"; - static std::vector<Value*> val(const RValue<UShort>& v) { return {v.value}; } + static std::string fmt(const RValue<UShort>& v) { return "%u"; } + static std::vector<Value*> val(const RValue<UShort>& v); }; template <> struct PrintValue::Ty<UShort4> { - static constexpr const char* fmt = "[%u, %u, %u, %u]"; + static std::string fmt(const RValue<UShort4>& v) { return "[%u, %u, %u, %u]"; } static std::vector<Value*> val(const RValue<UShort4>& v); }; template <> struct PrintValue::Ty<Float> { - static constexpr const char* fmt = "[%f]"; + static std::string fmt(const RValue<Float>& v) { return "[%f]"; } static std::vector<Value*> val(const RValue<Float>& v); }; template <> struct PrintValue::Ty<Float4> { - static constexpr const char* fmt = "[%f, %f, %f, %f]"; + static std::string fmt(const RValue<Float4>& v) { return "[%f, %f, %f, %f]"; } static std::vector<Value*> val(const RValue<Float4>& v); }; template <> struct PrintValue::Ty<Long> { - static constexpr const char* fmt = "%lld"; + static std::string fmt(const RValue<Long>& v) { return "%lld"; } static std::vector<Value*> val(const RValue<Long>& v) { return {v.value}; } }; template <typename T> struct PrintValue::Ty< Pointer<T> > { - static constexpr const char* fmt = "%p"; + static std::string fmt(const RValue<Pointer<T>>& v) { return "%p"; } static std::vector<Value*> val(const RValue<Pointer<T>>& v) { return {v.value}; } }; template <typename T> struct PrintValue::Ty< Reference<T> > { - static constexpr const char* fmt = PrintValue::Ty<T>::fmt; + static std::string fmt(const Reference<T>& v) { return PrintValue::Ty<T>::fmt(v); } static std::vector<Value*> val(const Reference<T>& v) { return PrintValue::Ty<T>::val(v); } }; template <typename T> struct PrintValue::Ty< RValue<T> > { - static constexpr const char* fmt = PrintValue::Ty<T>::fmt; + static std::string fmt(const RValue<T>& v) { return PrintValue::Ty<T>::fmt(v); } static std::vector<Value*> val(const RValue<T>& v) { return PrintValue::Ty<T>::val(v); } };