mib created this revision.
mib added reviewers: labath, bulbazord, JDevlieghere, jingham.
mib added a project: LLDB.
Herald added a project: All.
mib requested review of this revision.
Herald added a subscriber: lldb-commits.

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 updates the `SBStructuredData::GetIntegerValue` by templating
it and specialize it for `int64_t` & `uint64_t` to avoid breaking the
current implementation. This way when called from python, the same
function will work for both signed and unsigned integers.

Finally, this patch audits all the caller of `StructuredData::Integer`
or `StructuredData::Integer::GetIntegerValue()` to use the proper type.

rdar://105575764

Signed-off-by: Med Ismail Bennani <ism...@bennani.ma>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150485

Files:
  lldb/bindings/interface/SBStructuredDataExtensions.i
  lldb/bindings/interfaces.swig
  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/BreakpointResolverName.cpp
  lldb/source/Core/FormatEntity.cpp
  lldb/source/Host/common/XML.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/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.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/Thread.cpp
  lldb/source/Utility/StructuredData.cpp
  lldb/tools/lldb-vscode/JSONUtils.cpp

Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -1162,7 +1162,11 @@
     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: lldb/source/Utility/StructuredData.cpp
===================================================================
--- lldb/source/Utility/StructuredData.cpp
+++ lldb/source/Utility/StructuredData.cpp
@@ -68,10 +68,10 @@
     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 @@
   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 @@
   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: lldb/source/Target/Thread.cpp
===================================================================
--- lldb/source/Target/Thread.cpp
+++ lldb/source/Target/Thread.cpp
@@ -1807,7 +1807,7 @@
           id->GetType() == eStructuredDataTypeInteger) {
         strm.Format("  Activity '{0}', {1:x}\n",
                     name->GetAsString()->GetValue(),
-                    id->GetAsInteger()->GetValue());
+                    id->GetUnsignedIntegerValue());
       }
       printed_activity = true;
     }
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
@@ -69,7 +69,7 @@
   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 @@
   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: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -152,7 +152,7 @@
   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 @@
   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: lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -479,7 +479,7 @@
 
   void SetInteger(int64_t value);
 
-  StructuredData::IntegerSP CreateStructuredInteger() const;
+  StructuredData::UnsignedIntegerSP CreateStructuredInteger() const;
 };
 
 class PythonBoolean : public TypedPythonObject<PythonBoolean> {
Index: lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -458,11 +458,16 @@
   *this = Take<PythonInteger>(PyLong_FromLongLong(value));
 }
 
-StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
-  StructuredData::IntegerSP result(new StructuredData::Integer);
-  // FIXME this is really not ideal.   Errors are silently converted to 0
+StructuredData::UnsignedIntegerSP
+PythonInteger::CreateStructuredInteger() const {
+  StructuredData::UnsignedIntegerSP result(
+      new StructuredData::UnsignedInteger());
+  // 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.
+
+  // FIXME: Now that StructuredData support signed interger, we should convert
+  // python integer properly, handling negative integers.
   llvm::Expected<unsigned long long> value = AsModuloUnsignedLongLong();
   if (!value) {
     llvm::consumeError(value.takeError());
Index: lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
+++ lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
@@ -280,7 +280,7 @@
         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: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -343,7 +343,7 @@
           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();
       }
 
@@ -1968,23 +1968,24 @@
                            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());
@@ -1998,11 +1999,11 @@
         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) {
@@ -2063,7 +2064,7 @@
       }
 
     } 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
   });
 
@@ -3812,10 +3813,8 @@
   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: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -2635,7 +2635,7 @@
     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: lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
===================================================================
--- lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -2370,7 +2370,7 @@
   if (!value)
     return LLDB_INVALID_ADDRESS;
 
-  return value->GetIntegerValue(LLDB_INVALID_ADDRESS);
+  return value->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS);
 }
 
 void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
Index: lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
===================================================================
--- lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
+++ lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
@@ -154,7 +154,7 @@
       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 @@
   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 @@
 
   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: lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
===================================================================
--- lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
+++ lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
@@ -217,7 +217,7 @@
         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 @@
     }
     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 @@
     } 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 @@
 
   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 @@
     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 @@
     } 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 @@
             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 @@
     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 @@
   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 @@
                    ->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 @@
         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 @@
 
         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: lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
===================================================================
--- lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
+++ lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
@@ -132,7 +132,7 @@
       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 @@
   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 @@
 
   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: lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
===================================================================
--- lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -570,7 +570,7 @@
         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: lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
===================================================================
--- lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -382,9 +382,9 @@
     }
     // clang-format on
     image_infos[i].address =
-        image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
+        image->GetValueForKey("load_address")->GetUnsignedIntegerValue();
     image_infos[i].mod_date =
-        image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
+        image->GetValueForKey("mod_date")->GetUnsignedIntegerValue();
     image_infos[i].file_spec.SetFile(
         image->GetValueForKey("pathname")->GetAsString()->GetValue(),
         FileSpec::Style::native);
@@ -392,13 +392,13 @@
     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 =
@@ -441,19 +441,19 @@
 
     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;
 
@@ -466,35 +466,32 @@
           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: lldb/source/Host/common/XML.cpp
===================================================================
--- lldb/source/Host/common/XML.cpp
+++ lldb/source/Host/common/XML.cpp
@@ -490,7 +490,7 @@
   } 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: lldb/source/Core/FormatEntity.cpp
===================================================================
--- lldb/source/Core/FormatEntity.cpp
+++ lldb/source/Core/FormatEntity.cpp
@@ -1008,7 +1008,7 @@
       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: lldb/source/Breakpoint/BreakpointResolverName.cpp
===================================================================
--- lldb/source/Breakpoint/BreakpointResolverName.cpp
+++ lldb/source/Breakpoint/BreakpointResolverName.cpp
@@ -197,8 +197,8 @@
     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: lldb/source/API/SBThread.cpp
===================================================================
--- lldb/source/API/SBThread.cpp
+++ lldb/source/API/SBThread.cpp
@@ -463,7 +463,7 @@
             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: lldb/source/API/SBStructuredData.cpp
===================================================================
--- lldb/source/API/SBStructuredData.cpp
+++ lldb/source/API/SBStructuredData.cpp
@@ -11,7 +11,6 @@
 
 #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"
@@ -162,12 +161,6 @@
   return result;
 }
 
-uint64_t SBStructuredData::GetIntegerValue(uint64_t fail_value) const {
-  LLDB_INSTRUMENT_VA(this, fail_value);
-
-  return m_impl_up->GetIntegerValue(fail_value);
-}
-
 double SBStructuredData::GetFloatValue(double fail_value) const {
   LLDB_INSTRUMENT_VA(this, fail_value);
 
Index: lldb/include/lldb/lldb-enumerations.h
===================================================================
--- lldb/include/lldb/lldb-enumerations.h
+++ lldb/include/lldb/lldb-enumerations.h
@@ -813,6 +813,8 @@
   eStructuredDataTypeGeneric,
   eStructuredDataTypeArray,
   eStructuredDataTypeInteger,
+  eStructuredDataTypeUnsignedInteger = eStructuredDataTypeInteger,
+  eStructuredDataTypeSignedInteger,
   eStructuredDataTypeFloat,
   eStructuredDataTypeBoolean,
   eStructuredDataTypeString,
Index: lldb/include/lldb/Utility/StructuredData.h
===================================================================
--- lldb/include/lldb/Utility/StructuredData.h
+++ lldb/include/lldb/Utility/StructuredData.h
@@ -48,10 +48,13 @@
 /// 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,7 +63,8 @@
 
   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;
@@ -94,14 +98,26 @@
                   : nullptr);
     }
 
-    Integer *GetAsInteger() {
-      return ((m_type == lldb::eStructuredDataTypeInteger)
-                  ? static_cast<Integer *>(this)
+    UnsignedInteger *GetAsUnsignedInteger() {
+      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 +218,16 @@
     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 +304,25 @@
 
     void AddItem(const ObjectSP &item) { m_items.push_back(item); }
 
+    template <typename T> void AddIntegerItem(T value) {
+      static_assert(std::is_integral<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 +332,36 @@
     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 +482,16 @@
     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 +582,14 @@
       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: lldb/include/lldb/Core/StructuredDataImpl.h
===================================================================
--- lldb/include/lldb/Core/StructuredDataImpl.h
+++ lldb/include/lldb/Core/StructuredDataImpl.h
@@ -129,7 +129,13 @@
   }
 
   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: lldb/include/lldb/API/SBStructuredData.h
===================================================================
--- lldb/include/lldb/API/SBStructuredData.h
+++ lldb/include/lldb/API/SBStructuredData.h
@@ -9,6 +9,8 @@
 #ifndef LLDB_API_SBSTRUCTUREDDATA_H
 #define LLDB_API_SBSTRUCTUREDDATA_H
 
+#include "lldb/Core/StructuredDataImpl.h"
+
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBModule.h"
 
@@ -54,7 +56,7 @@
 
   /// 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.
@@ -65,7 +67,14 @@
   lldb::SBStructuredData GetItemAtIndex(size_t idx) const;
 
   /// Return the integer value if this data structure is an integer type.
-  uint64_t GetIntegerValue(uint64_t fail_value = 0) const;
+  template <typename T> T GetIntegerValue(T fail_value = {}) const {
+    if constexpr (!std::is_integral_v<T>)
+      return fail_value;
+
+    return m_impl_up->GetType() == eStructuredDataTypeSignedInteger
+               ? m_impl_up->GetIntegerValue(static_cast<int64_t>(fail_value))
+               : m_impl_up->GetIntegerValue(static_cast<uint64_t>(fail_value));
+  }
 
   /// Return the floating point value if this data structure is a floating
   /// type.
Index: lldb/bindings/interfaces.swig
===================================================================
--- lldb/bindings/interfaces.swig
+++ lldb/bindings/interfaces.swig
@@ -179,6 +179,7 @@
 %include "./interface/SBSectionExtensions.i"
 %include "./interface/SBStreamExtensions.i"
 %include "./interface/SBStringListExtensions.i"
+%include "./interface/SBStructuredDataExtensions.i"
 %include "./interface/SBSymbolExtensions.i"
 %include "./interface/SBSymbolContextExtensions.i"
 %include "./interface/SBSymbolContextListExtensions.i"
Index: lldb/bindings/interface/SBStructuredDataExtensions.i
===================================================================
--- /dev/null
+++ lldb/bindings/interface/SBStructuredDataExtensions.i
@@ -0,0 +1,6 @@
+%extend lldb::SBStructuredData {
+#ifdef SWIGPYTHON
+    %template(GetIntegerValue) GetIntegerValue<int64_t>;
+    %template(GetIntegerValue) GetIntegerValue<uint64_t>;
+#endif
+}
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to