Improve the functionality of JSONNumber

* Add support for representing signed integers
* Add new constructors taking any signed or unsigned integer types

Differential revision: http://reviews.llvm.org/D15187

llvm-svn: 254715
This commit is contained in:
Tamas Berghammer 2015-12-04 13:23:35 +00:00
parent 7fa69cd5dd
commit 6d73750b2a
3 changed files with 116 additions and 44 deletions

View File

@ -97,9 +97,43 @@ namespace lldb_private {
class JSONNumber : public JSONValue
{
public:
JSONNumber ();
explicit JSONNumber (uint64_t i);
explicit JSONNumber (double d);
typedef std::shared_ptr<JSONNumber> SP;
// We cretae a constructor for all integer and floating point type with using templates and
// SFINAE to avoid having ambiguous overloads because of the implicit type promotion. If we
// would have constructors only with int64_t, uint64_t and double types then constructing a
// JSONNumber from an int32_t (or any other similar type) would fail to compile.
template <typename T,
typename std::enable_if<std::is_integral<T>::value &&
std::is_unsigned<T>::value>::type* = nullptr>
explicit JSONNumber (T u) :
JSONValue(JSONValue::Kind::Number),
m_data_type(DataType::Unsigned)
{
m_data.m_unsigned = u;
}
template <typename T,
typename std::enable_if<std::is_integral<T>::value &&
std::is_signed<T>::value>::type* = nullptr>
explicit JSONNumber (T s) :
JSONValue(JSONValue::Kind::Number),
m_data_type(DataType::Signed)
{
m_data.m_signed = s;
}
template <typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
explicit JSONNumber (T d) :
JSONValue(JSONValue::Kind::Number),
m_data_type(DataType::Double)
{
m_data.m_double = d;
}
~JSONNumber() override = default;
JSONNumber (const JSONNumber& s) = delete;
JSONNumber&
@ -107,32 +141,35 @@ namespace lldb_private {
void
Write(Stream& s) override;
typedef std::shared_ptr<JSONNumber> SP;
uint64_t
GetData () { return m_data; }
GetAsUnsigned() const;
uint64_t
GetAsSigned() const;
double
GetAsDouble()
{
if (m_is_integer)
return (double)m_data;
else
return m_double;
}
GetAsDouble() const;
static bool classof(const JSONValue *V)
{
return V->GetKind() == JSONValue::Kind::Number;
}
~JSONNumber() override = default;
private:
bool m_is_integer;
uint64_t m_data;
double m_double;
enum class DataType : uint8_t
{
Unsigned,
Signed,
Double
} m_data_type;
union
{
uint64_t m_unsigned;
int64_t m_signed;
double m_double;
} m_data;
};
class JSONTrue : public JSONValue

View File

@ -566,7 +566,7 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged)
thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
if (signum != 0)
thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(uint64_t(signum)));
thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
const std::string thread_name = thread_sp->GetName ();
if (! thread_name.empty())

View File

@ -60,38 +60,63 @@ JSONString::Write (Stream& s)
s.Printf("\"%s\"", json_string_quote_metachars(m_data).c_str());
}
JSONNumber::JSONNumber () :
JSONValue(JSONValue::Kind::Number),
m_is_integer(true),
m_data(0),
m_double(0.0)
uint64_t
JSONNumber::GetAsUnsigned() const
{
switch (m_data_type)
{
case DataType::Unsigned:
return m_data.m_unsigned;
case DataType::Signed:
return (uint64_t)m_data.m_signed;
case DataType::Double:
return (uint64_t)m_data.m_double;
}
}
JSONNumber::JSONNumber (uint64_t i) :
JSONValue(JSONValue::Kind::Number),
m_is_integer(true),
m_data(i),
m_double(0.0)
uint64_t
JSONNumber::GetAsSigned() const
{
switch (m_data_type)
{
case DataType::Unsigned:
return (int64_t)m_data.m_unsigned;
case DataType::Signed:
return m_data.m_signed;
case DataType::Double:
return (int64_t)m_data.m_double;
}
}
JSONNumber::JSONNumber (double d) :
JSONValue(JSONValue::Kind::Number),
m_is_integer(false),
m_data(0),
m_double(d)
double
JSONNumber::GetAsDouble() const
{
switch (m_data_type)
{
case DataType::Unsigned:
return (double)m_data.m_unsigned;
case DataType::Signed:
return (double)m_data.m_signed;
case DataType::Double:
return m_data.m_double;
}
}
void
JSONNumber::Write (Stream& s)
{
if (m_is_integer)
s.Printf("%" PRIu64, m_data);
else
s.Printf("%g", m_double);
switch (m_data_type)
{
case DataType::Unsigned:
s.Printf("%" PRIu64, m_data.m_unsigned);
break;
case DataType::Signed:
s.Printf("%" PRId64, m_data.m_signed);
break;
case DataType::Double:
s.Printf("%g", m_data.m_double);
break;
}
}
JSONTrue::JSONTrue () :
@ -617,10 +642,20 @@ JSONParser::ParseJSONValue ()
case JSONParser::Token::Integer:
{
bool success = false;
uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
if (success)
return JSONValue::SP(new JSONNumber(uval));
if (value.front() == '-')
{
bool success = false;
int64_t sval = StringConvert::ToSInt64(value.c_str(), 0, 0, &success);
if (success)
return JSONValue::SP(new JSONNumber(sval));
}
else
{
bool success = false;
uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
if (success)
return JSONValue::SP(new JSONNumber(uval));
}
}
break;