Index: lldb/trunk/include/lldb/Utility/JSON.h =================================================================== --- lldb/trunk/include/lldb/Utility/JSON.h +++ lldb/trunk/include/lldb/Utility/JSON.h @@ -97,9 +97,43 @@ class JSONNumber : public JSONValue { public: - JSONNumber (); - explicit JSONNumber (uint64_t i); - explicit JSONNumber (double d); + typedef std::shared_ptr 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 ::value && + std::is_unsigned::value>::type* = nullptr> + explicit JSONNumber (T u) : + JSONValue(JSONValue::Kind::Number), + m_data_type(DataType::Unsigned) + { + m_data.m_unsigned = u; + } + + template ::value && + std::is_signed::value>::type* = nullptr> + explicit JSONNumber (T s) : + JSONValue(JSONValue::Kind::Number), + m_data_type(DataType::Signed) + { + m_data.m_signed = s; + } + + template ::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 @@ void Write(Stream& s) override; - - typedef std::shared_ptr 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 Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -566,7 +566,7 @@ thread_obj_sp->SetObject("tid", std::make_shared(tid)); if (signum != 0) - thread_obj_sp->SetObject("signal", std::make_shared(uint64_t(signum))); + thread_obj_sp->SetObject("signal", std::make_shared(signum)); const std::string thread_name = thread_sp->GetName (); if (! thread_name.empty()) Index: lldb/trunk/source/Utility/JSON.cpp =================================================================== --- lldb/trunk/source/Utility/JSON.cpp +++ lldb/trunk/source/Utility/JSON.cpp @@ -60,38 +60,63 @@ 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 @@ 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;