[lldb] Add support for negative integer to {SB,}StructuredData
authorMed Ismail Bennani <ismail@bennani.ma>
Mon, 22 May 2023 20:52:09 +0000 (13:52 -0700)
committerMed Ismail Bennani <ismail@bennani.ma>
Mon, 22 May 2023 23:14:00 +0000 (16:14 -0700)
This patch refactors the `StructuredData::Integer` class to make it
templated, makes it private and adds 2 public specialization for both
`int64_t` & `uint64_t` with a public type aliases, respectively
`SignedInteger` & `UnsignedInteger`.

It adds new getter for signed and unsigned interger values to the
`StructuredData::Object` base class and changes the implementation of
`StructuredData::Array::GetItemAtIndexAsInteger` and
`StructuredData::Dictionary::GetValueForKeyAsInteger` to support signed
and unsigned integers.

This patch also adds 2 new `Get{Signed,Unsigned}IntegerValue` to the
`SBStructuredData` class and marks `GetIntegerValue` as deprecated.

Finally, this patch audits all the caller of `StructuredData::Integer`
or `StructuredData::GetIntegerValue` to use the proper type as well the
various tests that uses `SBStructuredData.GetIntegerValue`.

rdar://105575764

Differential Revision: https://reviews.llvm.org/D150485

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
37 files changed:
lldb/include/lldb/API/SBStructuredData.h
lldb/include/lldb/Core/StructuredDataImpl.h
lldb/include/lldb/Utility/StructuredData.h
lldb/include/lldb/lldb-enumerations.h
lldb/source/API/SBStructuredData.cpp
lldb/source/API/SBThread.cpp
lldb/source/Breakpoint/BreakpointOptions.cpp
lldb/source/Breakpoint/BreakpointResolver.cpp
lldb/source/Breakpoint/BreakpointResolverAddress.cpp
lldb/source/Breakpoint/BreakpointResolverName.cpp
lldb/source/Core/FormatEntity.cpp
lldb/source/Host/common/XML.cpp
lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp
lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
lldb/source/Target/DynamicRegisterInfo.cpp
lldb/source/Target/Thread.cpp
lldb/source/Utility/StructuredData.cpp
lldb/test/API/commands/target/stop-hooks/stop_hook.py
lldb/test/API/functionalities/step_scripted/Steps.py
lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
lldb/tools/lldb-vscode/JSONUtils.cpp
lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

index 75f8ebb..2f62638 100644 (file)
@@ -57,7 +57,7 @@ public:
 
   /// Fill keys with the keys in this object and return true if this data
   /// structure is a dictionary.  Returns false otherwise.
-   bool GetKeys(lldb::SBStringList &keys) const;
+  bool GetKeys(lldb::SBStringList &keys) const;
 
   /// Return the value corresponding to a key if this data structure
   /// is a dictionary type.
@@ -68,6 +68,12 @@ public:
   lldb::SBStructuredData GetItemAtIndex(size_t idx) const;
 
   /// Return the integer value if this data structure is an integer type.
+  uint64_t GetUnsignedIntegerValue(uint64_t fail_value = 0) const;
+  /// Return the integer value if this data structure is an integer type.
+  int64_t GetSignedIntegerValue(int64_t fail_value = 0) const;
+
+  LLDB_DEPRECATED("Specify if the value is signed or unsigned",
+                  "uint64_t GetUnsignedIntegerValue(uint64_t fail_value = 0)")
   uint64_t GetIntegerValue(uint64_t fail_value = 0) const;
 
   /// Return the floating point value if this data structure is a floating
index 16dbc52..3dfb7af 100644 (file)
@@ -129,7 +129,13 @@ public:
   }
 
   uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
-    return (m_data_sp ? m_data_sp->GetIntegerValue(fail_value) : fail_value);
+    return (m_data_sp ? m_data_sp->GetUnsignedIntegerValue(fail_value)
+                      : fail_value);
+  }
+
+  int64_t GetIntegerValue(int64_t fail_value = 0) const {
+    return (m_data_sp ? m_data_sp->GetSignedIntegerValue(fail_value)
+                      : fail_value);
   }
 
   double GetFloatValue(double fail_value = 0.0) const {
index 8bc4431..d6b51f7 100644 (file)
@@ -26,6 +26,7 @@
 #include <string>
 #include <type_traits>
 #include <utility>
+#include <variant>
 #include <vector>
 
 namespace lldb_private {
@@ -48,10 +49,13 @@ namespace lldb_private {
 /// that may be present.
 
 class StructuredData {
+  template <typename N> class Integer;
+
 public:
   class Object;
   class Array;
-  class Integer;
+  using UnsignedInteger = Integer<uint64_t>;
+  using SignedInteger = Integer<int64_t>;
   class Float;
   class Boolean;
   class String;
@@ -60,13 +64,16 @@ public:
 
   typedef std::shared_ptr<Object> ObjectSP;
   typedef std::shared_ptr<Array> ArraySP;
-  typedef std::shared_ptr<Integer> IntegerSP;
+  typedef std::shared_ptr<UnsignedInteger> UnsignedIntegerSP;
+  typedef std::shared_ptr<SignedInteger> SignedIntegerSP;
   typedef std::shared_ptr<Float> FloatSP;
   typedef std::shared_ptr<Boolean> BooleanSP;
   typedef std::shared_ptr<String> StringSP;
   typedef std::shared_ptr<Dictionary> DictionarySP;
   typedef std::shared_ptr<Generic> GenericSP;
 
+  typedef std::variant<UnsignedIntegerSP, SignedIntegerSP> IntegerSP;
+
   class Object : public std::enable_shared_from_this<Object> {
   public:
     Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid)
@@ -94,14 +101,28 @@ public:
                   : nullptr);
     }
 
-    Integer *GetAsInteger() {
-      return ((m_type == lldb::eStructuredDataTypeInteger)
-                  ? static_cast<Integer *>(this)
+    UnsignedInteger *GetAsUnsignedInteger() {
+      // NOTE: For backward compatibility, eStructuredDataTypeInteger is
+      // the same as eStructuredDataTypeUnsignedInteger.
+      return ((m_type == lldb::eStructuredDataTypeInteger ||
+               m_type == lldb::eStructuredDataTypeUnsignedInteger)
+                  ? static_cast<UnsignedInteger *>(this)
+                  : nullptr);
+    }
+
+    SignedInteger *GetAsSignedInteger() {
+      return ((m_type == lldb::eStructuredDataTypeSignedInteger)
+                  ? static_cast<SignedInteger *>(this)
                   : nullptr);
     }
 
-    uint64_t GetIntegerValue(uint64_t fail_value = 0) {
-      Integer *integer = GetAsInteger();
+    uint64_t GetUnsignedIntegerValue(uint64_t fail_value = 0) {
+      UnsignedInteger *integer = GetAsUnsignedInteger();
+      return ((integer != nullptr) ? integer->GetValue() : fail_value);
+    }
+
+    int64_t GetSignedIntegerValue(int64_t fail_value = 0) {
+      SignedInteger *integer = GetAsSignedInteger();
       return ((integer != nullptr) ? integer->GetValue() : fail_value);
     }
 
@@ -202,9 +223,16 @@ public:
     bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
       ObjectSP value_sp = GetItemAtIndex(idx);
       if (value_sp.get()) {
-        if (auto int_value = value_sp->GetAsInteger()) {
-          result = static_cast<IntType>(int_value->GetValue());
-          return true;
+        if constexpr (std::numeric_limits<IntType>::is_signed) {
+          if (auto signed_value = value_sp->GetAsSignedInteger()) {
+            result = static_cast<IntType>(signed_value->GetValue());
+            return true;
+          }
+        } else {
+          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
+            result = static_cast<IntType>(unsigned_value->GetValue());
+            return true;
+          }
         }
       }
       return false;
@@ -281,6 +309,26 @@ public:
 
     void AddItem(const ObjectSP &item) { m_items.push_back(item); }
 
+    template <typename T> void AddIntegerItem(T value) {
+      static_assert(std::is_integral<T>::value ||
+                        std::is_floating_point<T>::value,
+                    "value type should be integral");
+      if constexpr (std::numeric_limits<T>::is_signed)
+        AddItem(std::make_shared<SignedInteger>(value));
+      else
+        AddItem(std::make_shared<UnsignedInteger>(value));
+    }
+
+    void AddFloatItem(double value) { AddItem(std::make_shared<Float>(value)); }
+
+    void AddStringItem(llvm::StringRef value) {
+      AddItem(std::make_shared<String>(std::move(value)));
+    }
+
+    void AddBooleanItem(bool value) {
+      AddItem(std::make_shared<Boolean>(value));
+    }
+
     void Serialize(llvm::json::OStream &s) const override;
 
     void GetDescription(lldb_private::Stream &s) const override;
@@ -290,25 +338,36 @@ public:
     collection m_items;
   };
 
-  class Integer : public Object {
-  public:
-    Integer(uint64_t i = 0)
-        : Object(lldb::eStructuredDataTypeInteger), m_value(i) {}
+private:
+  template <typename N> class Integer : public Object {
+    static_assert(std::is_integral<N>::value, "N must be an integral type");
 
+  public:
+    Integer(N i = 0)
+        : Object(std::numeric_limits<N>::is_signed
+                     ? lldb::eStructuredDataTypeSignedInteger
+                     : lldb::eStructuredDataTypeUnsignedInteger),
+          m_value(i) {}
     ~Integer() override = default;
 
-    void SetValue(uint64_t value) { m_value = value; }
+    void SetValue(N value) { m_value = value; }
 
-    uint64_t GetValue() { return m_value; }
+    N GetValue() { return m_value; }
 
-    void Serialize(llvm::json::OStream &s) const override;
+    void Serialize(llvm::json::OStream &s) const override {
+      s.value(static_cast<N>(m_value));
+    }
 
-    void GetDescription(lldb_private::Stream &s) const override;
+    void GetDescription(lldb_private::Stream &s) const override {
+      s.Printf(std::numeric_limits<N>::is_signed ? "%" PRId64 : "%" PRIu64,
+               static_cast<N>(m_value));
+    }
 
   protected:
-    uint64_t m_value;
+    N m_value;
   };
 
+public:
   class Float : public Object {
   public:
     Float(double d = 0.0)
@@ -429,9 +488,16 @@ public:
     bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
       ObjectSP value_sp = GetValueForKey(key);
       if (value_sp) {
-        if (auto int_value = value_sp->GetAsInteger()) {
-          result = static_cast<IntType>(int_value->GetValue());
-          return true;
+        if constexpr (std::numeric_limits<IntType>::is_signed) {
+          if (auto signed_value = value_sp->GetAsSignedInteger()) {
+            result = static_cast<IntType>(signed_value->GetValue());
+            return true;
+          }
+        } else {
+          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
+            result = static_cast<IntType>(unsigned_value->GetValue());
+            return true;
+          }
         }
       }
       return false;
@@ -522,8 +588,14 @@ public:
       m_dict[key_cs] = std::move(value_sp);
     }
 
-    void AddIntegerItem(llvm::StringRef key, uint64_t value) {
-      AddItem(key, std::make_shared<Integer>(value));
+    template <typename T> void AddIntegerItem(llvm::StringRef key, T value) {
+      static_assert(std::is_integral<T>::value ||
+                        std::is_floating_point<T>::value,
+                    "value type should be integral");
+      if constexpr (std::numeric_limits<T>::is_signed)
+        AddItem(key, std::make_shared<SignedInteger>(value));
+      else
+        AddItem(key, std::make_shared<UnsignedInteger>(value));
     }
 
     void AddFloatItem(llvm::StringRef key, double value) {
index cb443bf..524a478 100644 (file)
@@ -819,7 +819,9 @@ enum StructuredDataType {
   eStructuredDataTypeFloat,
   eStructuredDataTypeBoolean,
   eStructuredDataTypeString,
-  eStructuredDataTypeDictionary
+  eStructuredDataTypeDictionary,
+  eStructuredDataTypeSignedInteger,
+  eStructuredDataTypeUnsignedInteger = eStructuredDataTypeInteger,
 };
 
 FLAGS_ENUM(TypeClass){
index 445ed81..439921f 100644 (file)
@@ -7,11 +7,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/API/SBStructuredData.h"
+#include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Utility/Instrumentation.h"
 
 #include "lldb/API/SBStream.h"
 #include "lldb/API/SBStringList.h"
-#include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Target/StructuredDataPlugin.h"
 #include "lldb/Utility/Event.h"
 #include "lldb/Utility/Status.h"
@@ -165,6 +165,18 @@ lldb::SBStructuredData SBStructuredData::GetItemAtIndex(size_t idx) const {
 uint64_t SBStructuredData::GetIntegerValue(uint64_t fail_value) const {
   LLDB_INSTRUMENT_VA(this, fail_value);
 
+  return GetUnsignedIntegerValue(fail_value);
+}
+
+uint64_t SBStructuredData::GetUnsignedIntegerValue(uint64_t fail_value) const {
+  LLDB_INSTRUMENT_VA(this, fail_value);
+
+  return m_impl_up->GetIntegerValue(fail_value);
+}
+
+int64_t SBStructuredData::GetSignedIntegerValue(int64_t fail_value) const {
+  LLDB_INSTRUMENT_VA(this, fail_value);
+
   return m_impl_up->GetIntegerValue(fail_value);
 }
 
index bdd9311..a1f8a39 100644 (file)
@@ -461,7 +461,7 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
             success = true;
           }
           if (node->GetType() == eStructuredDataTypeInteger) {
-            strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
+            strm.Printf("0x%" PRIx64, node->GetUnsignedIntegerValue());
             success = true;
           }
           if (node->GetType() == eStructuredDataTypeFloat) {
index 31779fb..268c523 100644 (file)
@@ -230,7 +230,7 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData(
   bool enabled = true;
   bool one_shot = false;
   bool auto_continue = false;
-  int32_t ignore_count = 0;
+  uint32_t ignore_count = 0;
   llvm::StringRef condition_ref("");
   Flags set_options;
 
index 5c03798..c1e77d3 100644 (file)
@@ -102,7 +102,7 @@ BreakpointResolverSP BreakpointResolver::CreateFromStructuredData(
     return result_sp;
   }
 
-  lldb::addr_t offset;
+  lldb::offset_t offset;
   success = subclass_options->GetValueForKeyAsInteger(
       GetKey(OptionNames::Offset), offset);
   if (!success) {
index c173fc0..26f2891 100644 (file)
@@ -34,7 +34,7 @@ BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData(
     const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict,
     Status &error) {
   llvm::StringRef module_name;
-  lldb::addr_t addr_offset;
+  lldb::offset_t addr_offset;
   FileSpec module_filespec;
   bool success;
 
index d7cff7f..b533bdf 100644 (file)
@@ -104,7 +104,7 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData(
     }
   }
 
-  lldb::addr_t offset = 0;
+  lldb::offset_t offset = 0;
   success =
       options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Offset), offset);
   if (!success) {
@@ -197,8 +197,8 @@ StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() {
     for (auto lookup : m_lookups) {
       names_sp->AddItem(StructuredData::StringSP(
           new StructuredData::String(lookup.GetName().GetStringRef())));
-      name_masks_sp->AddItem(StructuredData::IntegerSP(
-          new StructuredData::Integer(lookup.GetNameTypeMask())));
+      name_masks_sp->AddItem(StructuredData::UnsignedIntegerSP(
+          new StructuredData::UnsignedInteger(lookup.GetNameTypeMask())));
     }
     options_dict_sp->AddItem(GetKey(OptionNames::SymbolNameArray), names_sp);
     options_dict_sp->AddItem(GetKey(OptionNames::NameMaskArray), name_masks_sp);
index 80d77e1..00ab202 100644 (file)
@@ -1008,7 +1008,7 @@ static bool FormatThreadExtendedInfoRecurse(
       const char *token_format = "0x%4.4" PRIx64;
       if (!entry.printf_format.empty())
         token_format = entry.printf_format.c_str();
-      s.Printf(token_format, value->GetAsInteger()->GetValue());
+      s.Printf(token_format, value->GetUnsignedIntegerValue());
       return true;
     } else if (value->GetType() == eStructuredDataTypeFloat) {
       s.Printf("%f", value->GetAsFloat()->GetValue());
index 2d48175..bb2a729 100644 (file)
@@ -490,7 +490,7 @@ static StructuredData::ObjectSP CreatePlistValue(XMLNode node) {
   } else if (element_name == "integer") {
     uint64_t value = 0;
     node.GetElementTextAsUnsigned(value, 0, 0);
-    return StructuredData::ObjectSP(new StructuredData::Integer(value));
+    return StructuredData::ObjectSP(new StructuredData::UnsignedInteger(value));
   } else if ((element_name == "string") || (element_name == "data") ||
              (element_name == "date")) {
     std::string text;
index a01c190..8f50782 100644 (file)
@@ -102,8 +102,26 @@ Status OptionGroupPythonClassWithDict::SetOptionValue(
       if (!m_dict_sp)
         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
       if (!m_current_key.empty()) {
-          m_dict_sp->AddStringItem(m_current_key, option_arg);
-          m_current_key.clear();
+        if (!option_arg.empty()) {
+          double d = 0;
+          std::string opt = option_arg.lower();
+
+          if (llvm::to_integer(option_arg, d)) {
+            if (opt[0] == '-')
+              m_dict_sp->AddIntegerItem(m_current_key, static_cast<int64_t>(d));
+            else
+              m_dict_sp->AddIntegerItem(m_current_key,
+                                        static_cast<uint64_t>(d));
+          } else if (llvm::to_float(option_arg, d)) {
+            m_dict_sp->AddFloatItem(m_current_key, d);
+          } else if (opt == "true" || opt == "false") {
+            m_dict_sp->AddBooleanItem(m_current_key, opt == "true");
+          } else {
+            m_dict_sp->AddStringItem(m_current_key, option_arg);
+          }
+        }
+
+        m_current_key.clear();
       }
       else
         error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
index 8bcc935..4aaf014 100644 (file)
@@ -381,7 +381,7 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
     }
     // clang-format on
     image_infos[i].address =
-        image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
+        image->GetValueForKey("load_address")->GetUnsignedIntegerValue();
     image_infos[i].file_spec.SetFile(
         image->GetValueForKey("pathname")->GetAsString()->GetValue(),
         FileSpec::Style::native);
@@ -389,13 +389,13 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
     StructuredData::Dictionary *mh =
         image->GetValueForKey("mach_header")->GetAsDictionary();
     image_infos[i].header.magic =
-        mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
+        mh->GetValueForKey("magic")->GetUnsignedIntegerValue();
     image_infos[i].header.cputype =
-        mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
+        mh->GetValueForKey("cputype")->GetUnsignedIntegerValue();
     image_infos[i].header.cpusubtype =
-        mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
+        mh->GetValueForKey("cpusubtype")->GetUnsignedIntegerValue();
     image_infos[i].header.filetype =
-        mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
+        mh->GetValueForKey("filetype")->GetUnsignedIntegerValue();
 
     if (image->HasKey("min_version_os_name")) {
       std::string os_name =
@@ -438,19 +438,19 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
 
     if (mh->HasKey("flags"))
       image_infos[i].header.flags =
-          mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
+          mh->GetValueForKey("flags")->GetUnsignedIntegerValue();
     else
       image_infos[i].header.flags = 0;
 
     if (mh->HasKey("ncmds"))
       image_infos[i].header.ncmds =
-          mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
+          mh->GetValueForKey("ncmds")->GetUnsignedIntegerValue();
     else
       image_infos[i].header.ncmds = 0;
 
     if (mh->HasKey("sizeofcmds"))
       image_infos[i].header.sizeofcmds =
-          mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
+          mh->GetValueForKey("sizeofcmds")->GetUnsignedIntegerValue();
     else
       image_infos[i].header.sizeofcmds = 0;
 
@@ -463,35 +463,32 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
           segments->GetItemAtIndex(j)->GetAsDictionary();
       segment.name =
           ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue());
-      segment.vmaddr =
-          seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
-      segment.vmsize =
-          seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
+      segment.vmaddr = seg->GetValueForKey("vmaddr")->GetUnsignedIntegerValue();
+      segment.vmsize = seg->GetValueForKey("vmsize")->GetUnsignedIntegerValue();
       segment.fileoff =
-          seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
+          seg->GetValueForKey("fileoff")->GetUnsignedIntegerValue();
       segment.filesize =
-          seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
+          seg->GetValueForKey("filesize")->GetUnsignedIntegerValue();
       segment.maxprot =
-          seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
+          seg->GetValueForKey("maxprot")->GetUnsignedIntegerValue();
 
       // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
       // currently send them in the reply.
 
       if (seg->HasKey("initprot"))
         segment.initprot =
-            seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
+            seg->GetValueForKey("initprot")->GetUnsignedIntegerValue();
       else
         segment.initprot = 0;
 
       if (seg->HasKey("flags"))
-        segment.flags =
-            seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
+        segment.flags = seg->GetValueForKey("flags")->GetUnsignedIntegerValue();
       else
         segment.flags = 0;
 
       if (seg->HasKey("nsects"))
         segment.nsects =
-            seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
+            seg->GetValueForKey("nsects")->GetUnsignedIntegerValue();
       else
         segment.nsects = 0;
 
index dedceb7..67e79fd 100644 (file)
@@ -570,7 +570,7 @@ bool DynamicLoaderMacOS::GetSharedCacheInformation(
         info_dict->HasKey("no_shared_cache") &&
         info_dict->HasKey("shared_cache_base_address")) {
       base_address = info_dict->GetValueForKey("shared_cache_base_address")
-                         ->GetIntegerValue(LLDB_INVALID_ADDRESS);
+                         ->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS);
       std::string uuid_str = std::string(
           info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue());
       if (!uuid_str.empty())
index 8ed29ca..b7cd2b1 100644 (file)
@@ -132,7 +132,7 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData(
       responsible_frame = frame;
 
     lldb::addr_t PC = addr.GetLoadAddress(&target);
-    trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC)));
+    trace->AddIntegerItem(PC);
   }
 
   auto *d = new StructuredData::Dictionary();
@@ -252,7 +252,7 @@ InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo(
   std::vector<lldb::addr_t> PCs;
   auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray();
   trace->ForEach([&PCs](StructuredData::Object *PC) -> bool {
-    PCs.push_back(PC->GetAsInteger()->GetValue());
+    PCs.push_back(PC->GetUnsignedIntegerValue());
     return true;
   });
 
@@ -261,7 +261,7 @@ InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo(
 
   StructuredData::ObjectSP thread_id_obj =
       info->GetObjectForDotSeparatedPath("tid");
-  tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
+  tid_t tid = thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0;
 
   // We gather symbolication addresses above, so no need for HistoryThread to
   // try to infer the call addresses.
index 946e4b3..e2354c2 100644 (file)
@@ -217,7 +217,7 @@ CreateStackTrace(ValueObjectSP o,
         trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0);
     if (trace_addr == 0)
       break;
-    trace_sp->AddItem(std::make_shared<StructuredData::Integer>(trace_addr));
+    trace_sp->AddIntegerItem(trace_addr);
   }
   return trace_sp;
 }
@@ -668,13 +668,11 @@ InstrumentationRuntimeTSan::GenerateSummary(StructuredData::ObjectSP report) {
     }
     addr_t addr = loc->GetAsDictionary()
                       ->GetValueForKey("address")
-                      ->GetAsInteger()
-                      ->GetValue();
+                      ->GetUnsignedIntegerValue();
     if (addr == 0)
       addr = loc->GetAsDictionary()
                  ->GetValueForKey("start")
-                 ->GetAsInteger()
-                 ->GetValue();
+                 ->GetUnsignedIntegerValue();
 
     if (addr != 0) {
       std::string global_name = GetSymbolNameFromAddress(process_sp, addr);
@@ -686,8 +684,7 @@ InstrumentationRuntimeTSan::GenerateSummary(StructuredData::ObjectSP report) {
     } else {
       int fd = loc->GetAsDictionary()
                    ->GetValueForKey("file_descriptor")
-                   ->GetAsInteger()
-                   ->GetValue();
+                   ->GetSignedIntegerValue();
       if (fd != 0) {
         summary = summary + " on file descriptor " + Sprintf("%d", fd);
       }
@@ -703,8 +700,8 @@ addr_t InstrumentationRuntimeTSan::GetMainRacyAddress(
 
   report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach(
       [&result](StructuredData::Object *o) -> bool {
-        addr_t addr =
-            o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
+        addr_t addr = o->GetObjectForDotSeparatedPath("address")
+                          ->GetUnsignedIntegerValue();
         if (addr < result)
           result = addr;
         return true;
@@ -733,8 +730,8 @@ std::string InstrumentationRuntimeTSan::GetLocationDescription(
     if (type == "global") {
       global_addr = loc->GetAsDictionary()
                         ->GetValueForKey("address")
-                        ->GetAsInteger()
-                        ->GetValue();
+                        ->GetUnsignedIntegerValue();
+
       global_name = GetSymbolNameFromAddress(process_sp, global_addr);
       if (!global_name.empty()) {
         result = Sprintf("'%s' is a global variable (0x%llx)",
@@ -752,12 +749,12 @@ std::string InstrumentationRuntimeTSan::GetLocationDescription(
     } else if (type == "heap") {
       addr_t addr = loc->GetAsDictionary()
                         ->GetValueForKey("start")
-                        ->GetAsInteger()
-                        ->GetValue();
-      long size = loc->GetAsDictionary()
-                      ->GetValueForKey("size")
-                      ->GetAsInteger()
-                      ->GetValue();
+                        ->GetUnsignedIntegerValue();
+
+      size_t size = loc->GetAsDictionary()
+                        ->GetValueForKey("size")
+                        ->GetUnsignedIntegerValue();
+
       std::string object_type = std::string(loc->GetAsDictionary()
                                                 ->GetValueForKey("object_type")
                                                 ->GetAsString()
@@ -770,22 +767,22 @@ std::string InstrumentationRuntimeTSan::GetLocationDescription(
             Sprintf("Location is a %ld-byte heap object at 0x%llx", size, addr);
       }
     } else if (type == "stack") {
-      int tid = loc->GetAsDictionary()
-                    ->GetValueForKey("thread_id")
-                    ->GetAsInteger()
-                    ->GetValue();
+      tid_t tid = loc->GetAsDictionary()
+                      ->GetValueForKey("thread_id")
+                      ->GetUnsignedIntegerValue();
+
       result = Sprintf("Location is stack of thread %d", tid);
     } else if (type == "tls") {
-      int tid = loc->GetAsDictionary()
-                    ->GetValueForKey("thread_id")
-                    ->GetAsInteger()
-                    ->GetValue();
+      tid_t tid = loc->GetAsDictionary()
+                      ->GetValueForKey("thread_id")
+                      ->GetUnsignedIntegerValue();
+
       result = Sprintf("Location is TLS of thread %d", tid);
     } else if (type == "fd") {
       int fd = loc->GetAsDictionary()
                    ->GetValueForKey("file_descriptor")
-                   ->GetAsInteger()
-                   ->GetValue();
+                   ->GetSignedIntegerValue();
+
       result = Sprintf("Location is file descriptor %d", fd);
     }
   }
@@ -848,8 +845,8 @@ bool InstrumentationRuntimeTSan::NotifyBreakpointHit(
     report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach(
         [&all_addresses_are_same,
          main_address](StructuredData::Object *o) -> bool {
-          addr_t addr =
-              o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
+          addr_t addr = o->GetObjectForDotSeparatedPath("address")
+                            ->GetUnsignedIntegerValue();
           if (main_address != addr)
             all_addresses_are_same = false;
           return true;
@@ -946,14 +943,16 @@ static std::string GenerateThreadName(const std::string &path,
   std::string result = "additional information";
 
   if (path == "mops") {
-    int size = o->GetObjectForDotSeparatedPath("size")->GetIntegerValue();
-    int thread_id =
-        o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+    size_t size =
+        o->GetObjectForDotSeparatedPath("size")->GetUnsignedIntegerValue();
+    tid_t thread_id =
+        o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue();
     bool is_write =
         o->GetObjectForDotSeparatedPath("is_write")->GetBooleanValue();
     bool is_atomic =
         o->GetObjectForDotSeparatedPath("is_atomic")->GetBooleanValue();
-    addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
+    addr_t addr =
+        o->GetObjectForDotSeparatedPath("address")->GetUnsignedIntegerValue();
 
     std::string addr_string = Sprintf(" at 0x%llx", addr);
 
@@ -970,44 +969,44 @@ static std::string GenerateThreadName(const std::string &path,
                    ->GetStringValue() == "swift-access-race") {
       result = Sprintf("modifying access by thread %d", thread_id);
     } else {
-      result = Sprintf("%s%s of size %d%s by thread %d",
+      result = Sprintf("%s%s of size %zu%s by thread %" PRIu64,
                        is_atomic ? "atomic " : "", is_write ? "write" : "read",
                        size, addr_string.c_str(), thread_id);
     }
   }
 
   if (path == "threads") {
-    int thread_id =
-        o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
-    result = Sprintf("Thread %d created", thread_id);
+    tid_t thread_id =
+        o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue();
+    result = Sprintf("Thread %zu created", thread_id);
   }
 
   if (path == "locs") {
     std::string type = std::string(
         o->GetAsDictionary()->GetValueForKey("type")->GetStringValue());
-    int thread_id =
-        o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
-    int fd =
-        o->GetObjectForDotSeparatedPath("file_descriptor")->GetIntegerValue();
+    tid_t thread_id =
+        o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue();
+    int fd = o->GetObjectForDotSeparatedPath("file_descriptor")
+                 ->GetSignedIntegerValue();
     if (type == "heap") {
-      result = Sprintf("Heap block allocated by thread %d", thread_id);
+      result = Sprintf("Heap block allocated by thread %" PRIu64, thread_id);
     } else if (type == "fd") {
-      result =
-          Sprintf("File descriptor %d created by thread %t", fd, thread_id);
+      result = Sprintf("File descriptor %d created by thread %" PRIu64, fd,
+                       thread_id);
     }
   }
 
   if (path == "mutexes") {
     int mutex_id =
-        o->GetObjectForDotSeparatedPath("mutex_id")->GetIntegerValue();
+        o->GetObjectForDotSeparatedPath("mutex_id")->GetSignedIntegerValue();
 
     result = Sprintf("Mutex M%d created", mutex_id);
   }
 
   if (path == "stacks") {
-    int thread_id =
-        o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
-    result = Sprintf("Thread %d", thread_id);
+    tid_t thread_id =
+        o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue();
+    result = Sprintf("Thread %" PRIu64, thread_id);
   }
 
   result[0] = toupper(result[0]);
@@ -1023,7 +1022,7 @@ static void AddThreadsForPath(const std::string &path,
         std::vector<lldb::addr_t> pcs;
         o->GetObjectForDotSeparatedPath("trace")->GetAsArray()->ForEach(
             [&pcs](StructuredData::Object *pc) -> bool {
-              pcs.push_back(pc->GetAsInteger()->GetValue());
+              pcs.push_back(pc->GetUnsignedIntegerValue());
               return true;
             });
 
@@ -1032,7 +1031,8 @@ static void AddThreadsForPath(const std::string &path,
 
         StructuredData::ObjectSP thread_id_obj =
             o->GetObjectForDotSeparatedPath("thread_os_id");
-        tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
+        tid_t tid =
+            thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0;
 
         ThreadSP new_thread_sp =
             std::make_shared<HistoryThread>(*process_sp, tid, pcs);
index 170dcd8..2e3c053 100644 (file)
@@ -154,7 +154,7 @@ StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData(
       continue;
 
     lldb::addr_t PC = FCA.GetLoadAddress(&target);
-    trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC)));
+    trace->AddIntegerItem(PC);
   }
 
   std::string IssueKind = RetrieveString(main_value, process_sp, ".issue_kind");
@@ -312,7 +312,7 @@ InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo(
   std::vector<lldb::addr_t> PCs;
   auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray();
   trace->ForEach([&PCs](StructuredData::Object *PC) -> bool {
-    PCs.push_back(PC->GetAsInteger()->GetValue());
+    PCs.push_back(PC->GetUnsignedIntegerValue());
     return true;
   });
 
@@ -321,7 +321,7 @@ InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo(
 
   StructuredData::ObjectSP thread_id_obj =
       info->GetObjectForDotSeparatedPath("tid");
-  tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
+  tid_t tid = thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0;
 
   // We gather symbolication addresses above, so no need for HistoryThread to
   // try to infer the call addresses.
index 7d376f2..cd34d78 100644 (file)
@@ -2370,7 +2370,7 @@ lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheBaseAddress() {
   if (!value)
     return LLDB_INVALID_ADDRESS;
 
-  return value->GetIntegerValue(LLDB_INVALID_ADDRESS);
+  return value->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS);
 }
 
 void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
index a6106dc..053d79b 100644 (file)
@@ -721,7 +721,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
           return false;
 
         // Signal number and signal name are required.
-        int signo;
+        uint64_t signo;
         if (!dict->GetValueForKeyAsInteger("signo", signo))
           return false;
 
index d43401c..d97e3a7 100644 (file)
@@ -2633,7 +2633,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer(
     uint16_t port = 0;
     if (StructuredData::ObjectSP port_osp =
             element->GetValueForKey(llvm::StringRef("port")))
-      port = port_osp->GetIntegerValue(0);
+      port = port_osp->GetUnsignedIntegerValue(0);
 
     std::string socket_name;
     if (StructuredData::ObjectSP socket_name_osp =
index 272cd4b..d20a022 100644 (file)
@@ -342,7 +342,7 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition(
           target_definition_sp->GetValueForKey("breakpoint-pc-offset");
       if (breakpoint_pc_offset_value) {
         if (auto breakpoint_pc_int_value =
-                breakpoint_pc_offset_value->GetAsInteger())
+                breakpoint_pc_offset_value->GetAsSignedInteger())
           m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
       }
 
@@ -1967,23 +1967,24 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
                            StructuredData::Object *object) -> bool {
     if (key == g_key_tid) {
       // thread in big endian hex
-      tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID);
+      tid = object->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID);
     } else if (key == g_key_metype) {
       // exception type in big endian hex
-      exc_type = object->GetIntegerValue(0);
+      exc_type = object->GetUnsignedIntegerValue(0);
     } else if (key == g_key_medata) {
       // exception data in big endian hex
       StructuredData::Array *array = object->GetAsArray();
       if (array) {
         array->ForEach([&exc_data](StructuredData::Object *object) -> bool {
-          exc_data.push_back(object->GetIntegerValue());
+          exc_data.push_back(object->GetUnsignedIntegerValue());
           return true; // Keep iterating through all array items
         });
       }
     } else if (key == g_key_name) {
       thread_name = std::string(object->GetStringValue());
     } else if (key == g_key_qaddr) {
-      thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
+      thread_dispatch_qaddr =
+          object->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS);
     } else if (key == g_key_queue_name) {
       queue_vars_valid = true;
       queue_name = std::string(object->GetStringValue());
@@ -1997,11 +1998,11 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
         queue_kind = eQueueKindConcurrent;
       }
     } else if (key == g_key_queue_serial_number) {
-      queue_serial_number = object->GetIntegerValue(0);
+      queue_serial_number = object->GetUnsignedIntegerValue(0);
       if (queue_serial_number != 0)
         queue_vars_valid = true;
     } else if (key == g_key_dispatch_queue_t) {
-      dispatch_queue_t = object->GetIntegerValue(0);
+      dispatch_queue_t = object->GetUnsignedIntegerValue(0);
       if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS)
         queue_vars_valid = true;
     } else if (key == g_key_associated_with_dispatch_queue) {
@@ -2062,7 +2063,7 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
       }
 
     } else if (key == g_key_signal)
-      signo = object->GetIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
+      signo = object->GetUnsignedIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
     return true; // Keep iterating through all dictionary key/value pairs
   });
 
@@ -3818,10 +3819,8 @@ StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
   StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
   StructuredData::ArraySP addresses(new StructuredData::Array);
 
-  for (auto addr : load_addresses) {
-    StructuredData::ObjectSP addr_sp(new StructuredData::Integer(addr));
-    addresses->AddItem(addr_sp);
-  }
+  for (auto addr : load_addresses)
+    addresses->AddIntegerItem(addr);
 
   args_dict->GetAsDictionary()->AddItem("solib_addresses", addresses);
 
index 46f99f6..5be1eff 100644 (file)
@@ -457,7 +457,7 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
       return error_with_message("Couldn't create or get module.");
 
     lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
-    lldb::addr_t slide = LLDB_INVALID_OFFSET;
+    lldb::offset_t slide = LLDB_INVALID_OFFSET;
     dict->GetValueForKeyAsInteger("load_addr", load_addr);
     dict->GetValueForKeyAsInteger("slide", slide);
     if (load_addr == LLDB_INVALID_ADDRESS)
index 6877e9a..2c1516f 100644 (file)
@@ -280,7 +280,7 @@ bool ScriptedThread::CalculateStopInfo() {
         auto fetch_data = [&raw_codes](StructuredData::Object *obj) {
           if (!obj)
             return false;
-          raw_codes.push_back(obj->GetIntegerValue());
+          raw_codes.push_back(obj->GetUnsignedIntegerValue());
           return true;
         };
 
index 2291856..eee2f6f 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/Support/Errno.h"
 
 #include <cstdio>
+#include <variant>
 
 using namespace lldb_private;
 using namespace lldb;
@@ -101,7 +102,7 @@ Expected<long long> PythonObject::AsLongLong() const {
   return r;
 }
 
-Expected<long long> PythonObject::AsUnsignedLongLong() const {
+Expected<unsigned long long> PythonObject::AsUnsignedLongLong() const {
   if (!m_py_obj)
     return nullDeref();
   assert(!PyErr_Occurred());
@@ -117,6 +118,7 @@ Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const {
     return nullDeref();
   assert(!PyErr_Occurred());
   unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
+  // FIXME: We should fetch the exception message and hoist it.
   if (PyErr_Occurred())
     return exception();
   return r;
@@ -267,9 +269,15 @@ StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
   case PyObjectType::Boolean:
     return PythonBoolean(PyRefType::Borrowed, m_py_obj)
         .CreateStructuredBoolean();
-  case PyObjectType::Integer:
-    return PythonInteger(PyRefType::Borrowed, m_py_obj)
-        .CreateStructuredInteger();
+  case PyObjectType::Integer: {
+    StructuredData::IntegerSP int_sp =
+        PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger();
+    if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp))
+      return std::get<StructuredData::UnsignedIntegerSP>(int_sp);
+    if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp))
+      return std::get<StructuredData::SignedIntegerSP>(int_sp);
+    return nullptr;
+  };
   case PyObjectType::List:
     return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
   case PyObjectType::String:
@@ -459,17 +467,32 @@ void PythonInteger::SetInteger(int64_t value) {
 }
 
 StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
-  StructuredData::IntegerSP result(new StructuredData::Integer);
-  // FIXME this is really not ideal.   Errors are silently converted to 0
-  // and overflows are silently wrapped.   But we'd need larger changes
-  // to StructuredData to fix it, so that's how it is for now.
-  llvm::Expected<unsigned long long> value = AsModuloUnsignedLongLong();
-  if (!value) {
+  StructuredData::UnsignedIntegerSP uint_sp = CreateStructuredUnsignedInteger();
+  return uint_sp ? StructuredData::IntegerSP(uint_sp)
+                 : CreateStructuredSignedInteger();
+}
+
+StructuredData::UnsignedIntegerSP
+PythonInteger::CreateStructuredUnsignedInteger() const {
+  StructuredData::UnsignedIntegerSP result = nullptr;
+  llvm::Expected<unsigned long long> value = AsUnsignedLongLong();
+  if (!value)
     llvm::consumeError(value.takeError());
-    result->SetValue(0);
-  } else {
-    result->SetValue(value.get());
-  }
+  else
+    result = std::make_shared<StructuredData::UnsignedInteger>(value.get());
+
+  return result;
+}
+
+StructuredData::SignedIntegerSP
+PythonInteger::CreateStructuredSignedInteger() const {
+  StructuredData::SignedIntegerSP result = nullptr;
+  llvm::Expected<long long> value = AsLongLong();
+  if (!value)
+    llvm::consumeError(value.takeError());
+  else
+    result = std::make_shared<StructuredData::SignedInteger>(value.get());
+
   return result;
 }
 
index 3309220..61ec430 100644 (file)
@@ -354,7 +354,7 @@ public:
 
   llvm::Expected<long long> AsLongLong() const;
 
-  llvm::Expected<long long> AsUnsignedLongLong() const;
+  llvm::Expected<unsigned long long> AsUnsignedLongLong() const;
 
   // wraps on overflow, instead of raising an error.
   llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
@@ -480,6 +480,10 @@ public:
   void SetInteger(int64_t value);
 
   StructuredData::IntegerSP CreateStructuredInteger() const;
+
+  StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const;
+
+  StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const;
 };
 
 class PythonBoolean : public TypedPythonObject<PythonBoolean> {
index ad92185..019924f 100644 (file)
@@ -152,7 +152,7 @@ lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
   if (py_error.Fail())
     error = py_error;
 
-  return obj->GetIntegerValue(LLDB_INVALID_OFFSET);
+  return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET);
 }
 
 StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
@@ -173,7 +173,7 @@ lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
     return LLDB_INVALID_PROCESS_ID;
 
-  return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID);
+  return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
 }
 
 bool ScriptedProcessPythonInterface::IsAlive() {
index 1e0ca39..5603a15 100644 (file)
@@ -69,7 +69,7 @@ lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
     return LLDB_INVALID_THREAD_ID;
 
-  return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID);
+  return obj->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID);
 }
 
 std::optional<std::string> ScriptedThreadPythonInterface::GetName() {
@@ -89,7 +89,7 @@ lldb::StateType ScriptedThreadPythonInterface::GetState() {
   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
     return eStateInvalid;
 
-  return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid));
+  return static_cast<StateType>(obj->GetUnsignedIntegerValue(eStateInvalid));
 }
 
 std::optional<std::string> ScriptedThreadPythonInterface::GetQueue() {
index b4d02a0..d20f7c0 100644 (file)
@@ -262,7 +262,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
       return 0;
     }
 
-    int64_t bitsize = 0;
+    uint64_t bitsize = 0;
     if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) {
       Clear();
       printf("error: invalid or missing 'bitsize' key/value pair in register "
@@ -296,7 +296,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
                                              eEncodingUint);
 
     size_t set = 0;
-    if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) ||
+    if (!reg_info_dict->GetValueForKeyAsInteger("set", set) ||
         set >= m_sets.size()) {
       Clear();
       printf("error: invalid 'set' value in register dictionary, valid values "
index b5caf40..2eeb037 100644 (file)
@@ -1806,7 +1806,7 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level,
           id->GetType() == eStructuredDataTypeInteger) {
         strm.Format("  Activity '{0}', {1:x}\n",
                     name->GetAsString()->GetValue(),
-                    id->GetAsInteger()->GetValue());
+                    id->GetUnsignedIntegerValue());
       }
       printed_activity = true;
     }
index 1c30997..674a9fa 100644 (file)
@@ -68,10 +68,10 @@ static StructuredData::ObjectSP ParseJSONValue(json::Value &value) {
     return std::make_shared<StructuredData::Boolean>(*b);
 
   if (auto u = value.getAsUINT64())
-    return std::make_shared<StructuredData::Integer>(*u);
+    return std::make_shared<StructuredData::UnsignedInteger>(*u);
 
   if (auto i = value.getAsInteger())
-    return std::make_shared<StructuredData::Integer>(*i);
+    return std::make_shared<StructuredData::SignedInteger>(*i);
 
   if (auto d = value.getAsNumber())
     return std::make_shared<StructuredData::Float>(*d);
@@ -149,10 +149,6 @@ void StructuredData::Array::Serialize(json::OStream &s) const {
   s.arrayEnd();
 }
 
-void StructuredData::Integer::Serialize(json::OStream &s) const {
-  s.value(static_cast<int64_t>(m_value));
-}
-
 void StructuredData::Float::Serialize(json::OStream &s) const {
   s.value(m_value);
 }
@@ -183,10 +179,6 @@ void StructuredData::Generic::Serialize(json::OStream &s) const {
   s.value(llvm::formatv("{0:X}", m_object));
 }
 
-void StructuredData::Integer::GetDescription(lldb_private::Stream &s) const {
-  s.Printf("%" PRId64, static_cast<int64_t>(m_value));
-}
-
 void StructuredData::Float::GetDescription(lldb_private::Stream &s) const {
   s.Printf("%f", m_value);
 }
index 1abc2bd..7ec5a7a 100644 (file)
@@ -17,8 +17,7 @@ class stop_handler:
         increment = 1
         value = self.extra_args.GetValueForKey("increment")
         if value:
-            incr_as_str = value.GetStringValue(100)
-            increment = int(incr_as_str)
+            increment = value.GetUnsignedIntegerValue()
         else:
             stream.Print("Could not find increment in extra_args\n")
         frame = exe_ctx.GetFrame()
index 6b49de7..71ecd30 100644 (file)
@@ -98,7 +98,7 @@ class StepReportsStopOthers():
     
     def __init__(self, thread_plan, args_data, dict):
         self.thread_plan = thread_plan
-        self.key = args_data.GetValueForKey("token").GetStringValue(1000)
+        self.key = str(args_data.GetValueForKey("token").GetUnsignedIntegerValue(1000))
         
     def should_stop(self, event):
         self.thread_plan.SetPlanComplete(True)
index 0ab14c0..938cccc 100644 (file)
@@ -22,12 +22,17 @@ class TestStructuredDataAPI(TestBase):
         s = lldb.SBStream()
 
         dict_str = json.dumps(
-                {"key_dict":
-                 {"key_string":"STRING",
-                  "key_uint":0xffffffff00000000,
-                  "key_float":2.99,
-                  "key_bool":True,
-                  "key_array":["23","arr"]}})
+            {
+                "key_dict": {
+                    "key_string": "STRING",
+                    "key_uint": 0xFFFFFFFF00000000,
+                    "key_sint": -42,
+                    "key_float": 2.99,
+                    "key_bool": True,
+                    "key_array": ["23", "arr"],
+                }
+            }
+        )
         s.Print(dict_str)
         example = lldb.SBStructuredData()
 
@@ -46,7 +51,7 @@ class TestStructuredDataAPI(TestBase):
         self.assertSuccess(error, "GetDescription works")
         if not "key_float" in s.GetData():
             self.fail("FAILED: could not find key_float in description output")
-        
+
         dict_struct = lldb.SBStructuredData()
         dict_struct = example.GetValueForKey("key_dict")
 
@@ -59,6 +64,9 @@ class TestStructuredDataAPI(TestBase):
         # Tests for integer data type
         self.uint_struct_test(dict_struct)
 
+        # Tests for integer data type
+        self.sint_struct_test(dict_struct)
+
         # Tests for floating point data type
         self.double_struct_test(dict_struct)
 
@@ -90,7 +98,7 @@ class TestStructuredDataAPI(TestBase):
             self.fail("Wrong type returned: " + str(dict_struct.GetType()))
 
         # Check Size API for 'dictionary' type
-        if not dict_struct.GetSize() == 5:
+        if not dict_struct.GetSize() == 6:
             self.fail("Wrong no of elements returned: " +
                       str(dict_struct.GetSize()))
 
@@ -131,8 +139,8 @@ class TestStructuredDataAPI(TestBase):
         if not uint_struct.GetType() == lldb.eStructuredDataTypeInteger:
             self.fail("Wrong type returned: " + str(uint_struct.GetType()))
 
-        # Check API returning 'integer' value
-        output = uint_struct.GetIntegerValue()
+        # Check API returning unsigned integer value
+        output = uint_struct.GetUnsignedIntegerValue()
         if not output == 0xffffffff00000000:
             self.fail("wrong output: " + str(output))
 
@@ -140,6 +148,30 @@ class TestStructuredDataAPI(TestBase):
         # (e.g. getting a string value from an integer type structure)
         output = uint_struct.GetStringValue(25)
         if output:
+            self.fail("Valid string " + output + " returned for an integer object")
+
+    def sint_struct_test(self, dict_struct):
+        # Check a valid SBStructuredData containing an signed integer.
+        # We intentionally make this smaller than what an uint64_t can hold but
+        # still small enough to fit a int64_t
+        sint_struct = lldb.SBStructuredData()
+        sint_struct = dict_struct.GetValueForKey("key_sint")
+        if not sint_struct.IsValid():
+            self.fail("A valid object should have been returned")
+
+        # Check Type API
+        if not sint_struct.GetType() == lldb.eStructuredDataTypeSignedInteger:
+            self.fail("Wrong type returned: " + str(sint_struct.GetType()))
+
+        # Check API returning signed integer value
+        output = sint_struct.GetSignedIntegerValue()
+        if not output == -42:
+            self.fail("wrong output: " + str(output))
+
+        # Calling wrong API on a SBStructuredData
+        # (e.g. getting a string value from an integer type structure)
+        output = sint_struct.GetStringValue(69)
+        if output:
             self.fail(
                 "Valid string " +
                 output +
index 67455ab..d854bc6 100644 (file)
@@ -1161,8 +1161,11 @@ void FilterAndGetValueForKey(const lldb::SBStructuredData data, const char *key,
   case lldb::eStructuredDataTypeFloat:
     out.try_emplace(key_utf8, value.GetFloatValue());
     break;
-  case lldb::eStructuredDataTypeInteger:
-    out.try_emplace(key_utf8, value.GetIntegerValue());
+  case lldb::eStructuredDataTypeUnsignedInteger:
+    out.try_emplace(key_utf8, value.GetIntegerValue((uint64_t)0));
+    break;
+  case lldb::eStructuredDataTypeSignedInteger:
+    out.try_emplace(key_utf8, value.GetIntegerValue((int64_t)0));
     break;
   case lldb::eStructuredDataTypeArray: {
     lldb::SBStream contents;
index bf43881..eec494f 100644 (file)
@@ -297,7 +297,7 @@ TEST_F(GDBRemoteCommunicationClientTest, TestPacketSpeedJSON) {
   dict_sp = object_sp->GetAsDictionary();
   ASSERT_TRUE(bool(dict_sp));
 
-  int num_packets;
+  size_t num_packets;
   ASSERT_TRUE(dict_sp->GetValueForKeyAsInteger("num_packets", num_packets))
       << ss.GetString();
   ASSERT_EQ(10, num_packets);
index 733b919..3450712 100644 (file)
@@ -19,6 +19,8 @@
 
 #include "PythonTestSuite.h"
 
+#include <variant>
+
 using namespace lldb_private;
 using namespace lldb_private::python;
 using llvm::Error;
@@ -266,10 +268,23 @@ TEST_F(PythonDataObjectsTest, TestPythonStringToStr) {
 
 TEST_F(PythonDataObjectsTest, TestPythonIntegerToStr) {}
 
-TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredInteger) {
+TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredUnsignedInteger) {
   PythonInteger integer(7);
   auto int_sp = integer.CreateStructuredInteger();
-  EXPECT_EQ(7U, int_sp->GetValue());
+  EXPECT_TRUE(
+      std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp));
+  StructuredData::UnsignedIntegerSP uint_sp =
+      std::get<StructuredData::UnsignedIntegerSP>(int_sp);
+  EXPECT_EQ(7U, uint_sp->GetValue());
+}
+
+TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredSignedInteger) {
+  PythonInteger integer(-42);
+  auto int_sp = integer.CreateStructuredInteger();
+  EXPECT_TRUE(std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp));
+  StructuredData::SignedIntegerSP sint_sp =
+      std::get<StructuredData::SignedIntegerSP>(int_sp);
+  EXPECT_EQ(-42, sint_sp->GetValue());
 }
 
 TEST_F(PythonDataObjectsTest, TestPythonStringToStructuredString) {
@@ -358,7 +373,7 @@ TEST_F(PythonDataObjectsTest, TestPythonListToStructuredList) {
   EXPECT_EQ(lldb::eStructuredDataTypeString,
             array_sp->GetItemAtIndex(1)->GetType());
 
-  auto int_sp = array_sp->GetItemAtIndex(0)->GetAsInteger();
+  auto int_sp = array_sp->GetItemAtIndex(0)->GetAsUnsignedInteger();
   auto string_sp = array_sp->GetItemAtIndex(1)->GetAsString();
 
   EXPECT_EQ(long_value0, long(int_sp->GetValue()));
@@ -522,7 +537,7 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryToStructuredDictionary) {
   EXPECT_TRUE(dict_sp->HasKey(string_key1));
 
   auto string_sp = dict_sp->GetValueForKey(string_key0)->GetAsString();
-  auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsInteger();
+  auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsUnsignedInteger();
 
   EXPECT_EQ(string_value0, string_sp->GetValue());
   EXPECT_EQ(int_value1, long(int_sp->GetValue()));
@@ -592,7 +607,7 @@ TEST_F(PythonDataObjectsTest, TestExtractingUInt64ThroughStructuredData) {
           structured_dict_ptr->GetValueForKey(key_name);
       EXPECT_TRUE((bool)structured_addr_value_sp);
       const uint64_t extracted_value =
-          structured_addr_value_sp->GetIntegerValue(123);
+          structured_addr_value_sp->GetUnsignedIntegerValue(123);
       EXPECT_TRUE(extracted_value == value);
     }
   }