[Lldb-commits] [lldb] r254715 - Improve the functionality of JSONNumber

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Fri Dec 4 05:23:36 PST 2015


Author: tberghammer
Date: Fri Dec  4 07:23:35 2015
New Revision: 254715

URL: http://llvm.org/viewvc/llvm-project?rev=254715&view=rev
Log:
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

Modified:
    lldb/trunk/include/lldb/Utility/JSON.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
    lldb/trunk/source/Utility/JSON.cpp

Modified: lldb/trunk/include/lldb/Utility/JSON.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/JSON.h?rev=254715&r1=254714&r2=254715&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/JSON.h (original)
+++ lldb/trunk/include/lldb/Utility/JSON.h Fri Dec  4 07:23:35 2015
@@ -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

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp?rev=254715&r1=254714&r2=254715&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp Fri Dec  4 07:23:35 2015
@@ -566,7 +566,7 @@ GetJSONThreadsInfo(NativeProcessProtocol
 
         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())

Modified: lldb/trunk/source/Utility/JSON.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/JSON.cpp?rev=254715&r1=254714&r2=254715&view=diff
==============================================================================
--- lldb/trunk/source/Utility/JSON.cpp (original)
+++ lldb/trunk/source/Utility/JSON.cpp Fri Dec  4 07:23:35 2015
@@ -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;
 




More information about the lldb-commits mailing list