[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:
Med Ismail Bennani
2023-05-22 13:52:09 -07:00
parent 01c5ec3d62
commit 1370a1cb5b
37 changed files with 365 additions and 185 deletions

View 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;
}