[lldb] Add support for negative integer to {SB,}StructuredData
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>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user