diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h --- a/lldb/include/lldb/API/SBStructuredData.h +++ b/lldb/include/lldb/API/SBStructuredData.h @@ -57,7 +57,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. @@ -68,6 +68,12 @@ 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 diff --git a/lldb/include/lldb/Core/StructuredDataImpl.h b/lldb/include/lldb/Core/StructuredDataImpl.h --- a/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/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 { diff --git a/lldb/include/lldb/Utility/StructuredData.h b/lldb/include/lldb/Utility/StructuredData.h --- a/lldb/include/lldb/Utility/StructuredData.h +++ b/lldb/include/lldb/Utility/StructuredData.h @@ -26,6 +26,7 @@ #include #include #include +#include #include namespace lldb_private { @@ -48,10 +49,13 @@ /// that may be present. class StructuredData { + template class Integer; + public: class Object; class Array; - class Integer; + using UnsignedInteger = Integer; + using SignedInteger = Integer; class Float; class Boolean; class String; @@ -60,13 +64,16 @@ typedef std::shared_ptr ObjectSP; typedef std::shared_ptr ArraySP; - typedef std::shared_ptr IntegerSP; + typedef std::shared_ptr UnsignedIntegerSP; + typedef std::shared_ptr SignedIntegerSP; typedef std::shared_ptr FloatSP; typedef std::shared_ptr BooleanSP; typedef std::shared_ptr StringSP; typedef std::shared_ptr DictionarySP; typedef std::shared_ptr GenericSP; + typedef std::variant IntegerSP; + class Object : public std::enable_shared_from_this { public: Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid) @@ -94,14 +101,28 @@ : nullptr); } - Integer *GetAsInteger() { - return ((m_type == lldb::eStructuredDataTypeInteger) - ? static_cast(this) + UnsignedInteger *GetAsUnsignedInteger() { + // NOTE: For backward compatibility, eStructuredDataTypeInteger is + // the same as eStructuredDataTypeUnsignedInteger. + return ((m_type == lldb::eStructuredDataTypeInteger || + m_type == lldb::eStructuredDataTypeUnsignedInteger) + ? static_cast(this) + : nullptr); + } + + SignedInteger *GetAsSignedInteger() { + return ((m_type == lldb::eStructuredDataTypeSignedInteger) + ? static_cast(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 @@ 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(int_value->GetValue()); - return true; + if constexpr (std::numeric_limits::is_signed) { + if (auto signed_value = value_sp->GetAsSignedInteger()) { + result = static_cast(signed_value->GetValue()); + return true; + } + } else { + if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) { + result = static_cast(unsigned_value->GetValue()); + return true; + } } } return false; @@ -281,6 +309,26 @@ void AddItem(const ObjectSP &item) { m_items.push_back(item); } + template void AddIntegerItem(T value) { + static_assert(std::is_integral::value || + std::is_floating_point::value, + "value type should be integral"); + if constexpr (std::numeric_limits::is_signed) + AddItem(std::make_shared(value)); + else + AddItem(std::make_shared(value)); + } + + void AddFloatItem(double value) { AddItem(std::make_shared(value)); } + + void AddStringItem(llvm::StringRef value) { + AddItem(std::make_shared(std::move(value))); + } + + void AddBooleanItem(bool value) { + AddItem(std::make_shared(value)); + } + void Serialize(llvm::json::OStream &s) const override; void GetDescription(lldb_private::Stream &s) const override; @@ -290,25 +338,36 @@ collection m_items; }; - class Integer : public Object { - public: - Integer(uint64_t i = 0) - : Object(lldb::eStructuredDataTypeInteger), m_value(i) {} +private: + template class Integer : public Object { + static_assert(std::is_integral::value, "N must be an integral type"); + public: + Integer(N i = 0) + : Object(std::numeric_limits::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(m_value)); + } - void GetDescription(lldb_private::Stream &s) const override; + void GetDescription(lldb_private::Stream &s) const override { + s.Printf(std::numeric_limits::is_signed ? "%" PRId64 : "%" PRIu64, + static_cast(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 @@ 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(int_value->GetValue()); - return true; + if constexpr (std::numeric_limits::is_signed) { + if (auto signed_value = value_sp->GetAsSignedInteger()) { + result = static_cast(signed_value->GetValue()); + return true; + } + } else { + if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) { + result = static_cast(unsigned_value->GetValue()); + return true; + } } } return false; @@ -522,8 +588,14 @@ m_dict[key_cs] = std::move(value_sp); } - void AddIntegerItem(llvm::StringRef key, uint64_t value) { - AddItem(key, std::make_shared(value)); + template void AddIntegerItem(llvm::StringRef key, T value) { + static_assert(std::is_integral::value || + std::is_floating_point::value, + "value type should be integral"); + if constexpr (std::numeric_limits::is_signed) + AddItem(key, std::make_shared(value)); + else + AddItem(key, std::make_shared(value)); } void AddFloatItem(llvm::StringRef key, double value) { diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -819,7 +819,9 @@ eStructuredDataTypeFloat, eStructuredDataTypeBoolean, eStructuredDataTypeString, - eStructuredDataTypeDictionary + eStructuredDataTypeDictionary, + eStructuredDataTypeSignedInteger, + eStructuredDataTypeUnsignedInteger = eStructuredDataTypeInteger, }; FLAGS_ENUM(TypeClass){ diff --git a/lldb/source/API/SBStructuredData.cpp b/lldb/source/API/SBStructuredData.cpp --- a/lldb/source/API/SBStructuredData.cpp +++ b/lldb/source/API/SBStructuredData.cpp @@ -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 @@ 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); } diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -461,7 +461,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) { diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp --- a/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -230,7 +230,7 @@ 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; diff --git a/lldb/source/Breakpoint/BreakpointResolver.cpp b/lldb/source/Breakpoint/BreakpointResolver.cpp --- a/lldb/source/Breakpoint/BreakpointResolver.cpp +++ b/lldb/source/Breakpoint/BreakpointResolver.cpp @@ -102,7 +102,7 @@ return result_sp; } - lldb::addr_t offset; + lldb::offset_t offset; success = subclass_options->GetValueForKeyAsInteger( GetKey(OptionNames::Offset), offset); if (!success) { diff --git a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp --- a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp @@ -34,7 +34,7 @@ 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; diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -104,7 +104,7 @@ } } - lldb::addr_t offset = 0; + lldb::offset_t offset = 0; success = options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Offset), offset); if (!success) { @@ -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); diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp --- a/lldb/source/Core/FormatEntity.cpp +++ b/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()); diff --git a/lldb/source/Host/common/XML.cpp b/lldb/source/Host/common/XML.cpp --- a/lldb/source/Host/common/XML.cpp +++ b/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; diff --git a/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp b/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp --- a/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp +++ b/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp @@ -102,8 +102,26 @@ if (!m_dict_sp) m_dict_sp = std::make_shared(); 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(d)); + else + m_dict_sp->AddIntegerItem(m_current_key, + static_cast(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.", diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -381,7 +381,7 @@ } // 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 @@ 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 @@ 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 @@ 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; diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp +++ b/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()) diff --git a/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp --- a/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp +++ b/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 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. diff --git a/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp b/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp --- a/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp +++ b/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(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 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(*process_sp, tid, pcs); diff --git a/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp --- a/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp +++ b/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 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. diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/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() { diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp --- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -721,7 +721,7 @@ return false; // Signal number and signal name are required. - int signo; + uint64_t signo; if (!dict->GetValueForKeyAsInteger("signo", signo)) return false; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2633,7 +2633,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 = diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -342,7 +342,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(); } @@ -1967,23 +1967,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()); @@ -1997,11 +1998,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) { @@ -2062,7 +2063,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 }); @@ -3818,10 +3819,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); diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -457,7 +457,7 @@ 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) diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/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; }; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -354,7 +354,7 @@ llvm::Expected AsLongLong() const; - llvm::Expected AsUnsignedLongLong() const; + llvm::Expected AsUnsignedLongLong() const; // wraps on overflow, instead of raising an error. llvm::Expected AsModuloUnsignedLongLong() const; @@ -480,6 +480,10 @@ void SetInteger(int64_t value); StructuredData::IntegerSP CreateStructuredInteger() const; + + StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const; + + StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const; }; class PythonBoolean : public TypedPythonObject { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/Errno.h" #include +#include using namespace lldb_private; using namespace lldb; @@ -101,7 +102,7 @@ return r; } -Expected PythonObject::AsUnsignedLongLong() const { +Expected PythonObject::AsUnsignedLongLong() const { if (!m_py_obj) return nullDeref(); assert(!PyErr_Occurred()); @@ -117,6 +118,7 @@ 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 @@ 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(int_sp)) + return std::get(int_sp); + if (std::holds_alternative(int_sp)) + return std::get(int_sp); + return nullptr; + }; case PyObjectType::List: return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray(); case PyObjectType::String: @@ -459,17 +467,32 @@ } 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 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 value = AsUnsignedLongLong(); + if (!value) llvm::consumeError(value.takeError()); - result->SetValue(0); - } else { - result->SetValue(value.get()); - } + else + result = std::make_shared(value.get()); + + return result; +} + +StructuredData::SignedIntegerSP +PythonInteger::CreateStructuredSignedInteger() const { + StructuredData::SignedIntegerSP result = nullptr; + llvm::Expected value = AsLongLong(); + if (!value) + llvm::consumeError(value.takeError()); + else + result = std::make_shared(value.get()); + return result; } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/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() { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp +++ b/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 ScriptedThreadPythonInterface::GetName() { @@ -89,7 +89,7 @@ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return eStateInvalid; - return static_cast(obj->GetIntegerValue(eStateInvalid)); + return static_cast(obj->GetUnsignedIntegerValue(eStateInvalid)); } std::optional ScriptedThreadPythonInterface::GetQueue() { diff --git a/lldb/source/Target/DynamicRegisterInfo.cpp b/lldb/source/Target/DynamicRegisterInfo.cpp --- a/lldb/source/Target/DynamicRegisterInfo.cpp +++ b/lldb/source/Target/DynamicRegisterInfo.cpp @@ -262,7 +262,7 @@ 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 @@ eEncodingUint); size_t set = 0; - if (!reg_info_dict->GetValueForKeyAsInteger("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 " diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -1806,7 +1806,7 @@ id->GetType() == eStructuredDataTypeInteger) { strm.Format(" Activity '{0}', {1:x}\n", name->GetAsString()->GetValue(), - id->GetAsInteger()->GetValue()); + id->GetUnsignedIntegerValue()); } printed_activity = true; } diff --git a/lldb/source/Utility/StructuredData.cpp b/lldb/source/Utility/StructuredData.cpp --- a/lldb/source/Utility/StructuredData.cpp +++ b/lldb/source/Utility/StructuredData.cpp @@ -68,10 +68,10 @@ return std::make_shared(*b); if (auto u = value.getAsUINT64()) - return std::make_shared(*u); + return std::make_shared(*u); if (auto i = value.getAsInteger()) - return std::make_shared(*i); + return std::make_shared(*i); if (auto d = value.getAsNumber()) return std::make_shared(*d); @@ -149,10 +149,6 @@ s.arrayEnd(); } -void StructuredData::Integer::Serialize(json::OStream &s) const { - s.value(static_cast(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(m_value)); -} - void StructuredData::Float::GetDescription(lldb_private::Stream &s) const { s.Printf("%f", m_value); } diff --git a/lldb/test/API/commands/target/stop-hooks/stop_hook.py b/lldb/test/API/commands/target/stop-hooks/stop_hook.py --- a/lldb/test/API/commands/target/stop-hooks/stop_hook.py +++ b/lldb/test/API/commands/target/stop-hooks/stop_hook.py @@ -17,8 +17,7 @@ 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() diff --git a/lldb/test/API/functionalities/step_scripted/Steps.py b/lldb/test/API/functionalities/step_scripted/Steps.py --- a/lldb/test/API/functionalities/step_scripted/Steps.py +++ b/lldb/test/API/functionalities/step_scripted/Steps.py @@ -98,7 +98,7 @@ 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) diff --git a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py --- a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py +++ b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py @@ -22,12 +22,17 @@ 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 @@ 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 @@ # 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 @@ 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,14 +139,38 @@ 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)) # Calling wrong API on a SBStructuredData # (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 " + diff --git a/lldb/tools/lldb-vscode/JSONUtils.cpp b/lldb/tools/lldb-vscode/JSONUtils.cpp --- a/lldb/tools/lldb-vscode/JSONUtils.cpp +++ b/lldb/tools/lldb-vscode/JSONUtils.cpp @@ -1161,8 +1161,11 @@ 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; diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp --- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp @@ -297,7 +297,7 @@ 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); diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp --- a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp @@ -19,6 +19,8 @@ #include "PythonTestSuite.h" +#include + using namespace lldb_private; using namespace lldb_private::python; using llvm::Error; @@ -266,10 +268,23 @@ 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(int_sp)); + StructuredData::UnsignedIntegerSP uint_sp = + std::get(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(int_sp)); + StructuredData::SignedIntegerSP sint_sp = + std::get(int_sp); + EXPECT_EQ(-42, sint_sp->GetValue()); } TEST_F(PythonDataObjectsTest, TestPythonStringToStructuredString) { @@ -358,7 +373,7 @@ 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 @@ 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 @@ 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); } }