Make CompilerType::getBitSize() / getByteSize() return an optional result. NFC
The code in LLDB assumes that CompilerType and friends use the size 0
as a sentinel value to signal an error. This works for C++, where no
zero-sized type exists, but in many other programming languages
(including I believe C) types of size zero are possible and even
common. This is a particular pain point in swift-lldb, where extra
code exists to double-check that a type is *really* of size zero and
not an error at various locations.
To remedy this situation, this patch starts by converting
CompilerType::getBitSize() and getByteSize() to return an optional
result. To avoid wasting space, I hand-rolled my own optional data
type assuming that no type is larger than what fits into 63
bits. Follow-up patches would make similar changes to the ValueObject
hierarchy.
rdar://problem/47178964
Differential Revision: https://reviews.llvm.org/D56688
llvm-svn: 351214
diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp
index 1ce6ea5..bd942fd 100644
--- a/lldb/source/Core/Value.cpp
+++ b/lldb/source/Core/Value.cpp
@@ -224,8 +224,9 @@
{
const CompilerType &ast_type = GetCompilerType();
if (ast_type.IsValid())
- byte_size = ast_type.GetByteSize(
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
+ if (auto size = ast_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr))
+ byte_size = *size;
} break;
}
@@ -345,8 +346,9 @@
uint32_t limit_byte_size = UINT32_MAX;
if (ast_type.IsValid()) {
- limit_byte_size = ast_type.GetByteSize(
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
+ if (auto size = ast_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr))
+ limit_byte_size = *size;
}
if (limit_byte_size <= m_value.GetByteSize()) {
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index b0dd04a..1965d70 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -756,10 +756,12 @@
ExecutionContext exe_ctx(GetExecutionContextRef());
- const uint64_t item_type_size = pointee_or_element_compiler_type.GetByteSize(
+ auto item_type_size = pointee_or_element_compiler_type.GetByteSize(
exe_ctx.GetBestExecutionContextScope());
- const uint64_t bytes = item_count * item_type_size;
- const uint64_t offset = item_idx * item_type_size;
+ if (!item_type_size)
+ return 0;
+ const uint64_t bytes = item_count * *item_type_size;
+ const uint64_t offset = item_idx * *item_type_size;
if (item_idx == 0 && item_count == 1) // simply a deref
{
@@ -822,10 +824,10 @@
}
} break;
case eAddressTypeHost: {
- const uint64_t max_bytes =
+ auto max_bytes =
GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
- if (max_bytes > offset) {
- size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
+ if (max_bytes && *max_bytes > offset) {
+ size_t bytes_read = std::min<uint64_t>(*max_bytes - offset, bytes);
addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
break;
@@ -1818,14 +1820,15 @@
return synthetic_child_sp;
if (!can_create)
- return ValueObjectSP();
+ return {};
ExecutionContext exe_ctx(GetExecutionContextRef());
-
- ValueObjectChild *synthetic_child = new ValueObjectChild(
- *this, type, name_const_str,
- type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
- false, false, eAddressTypeInvalid, 0);
+ auto size = type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
+ if (!size)
+ return {};
+ ValueObjectChild *synthetic_child =
+ new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
+ false, false, eAddressTypeInvalid, 0);
if (synthetic_child) {
AddSyntheticChild(name_const_str, synthetic_child);
synthetic_child_sp = synthetic_child->GetSP();
@@ -1856,16 +1859,17 @@
return synthetic_child_sp;
if (!can_create)
- return ValueObjectSP();
+ return {};
const bool is_base_class = true;
ExecutionContext exe_ctx(GetExecutionContextRef());
-
- ValueObjectChild *synthetic_child = new ValueObjectChild(
- *this, type, name_const_str,
- type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
- is_base_class, false, eAddressTypeInvalid, 0);
+ auto size = type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
+ if (!size)
+ return {};
+ ValueObjectChild *synthetic_child =
+ new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
+ is_base_class, false, eAddressTypeInvalid, 0);
if (synthetic_child) {
AddSyntheticChild(name_const_str, synthetic_child);
synthetic_child_sp = synthetic_child->GetSP();
diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp
index e857702..f6e32c0 100644
--- a/lldb/source/Core/ValueObjectConstResult.cpp
+++ b/lldb/source/Core/ValueObjectConstResult.cpp
@@ -198,10 +198,11 @@
uint64_t ValueObjectConstResult::GetByteSize() {
ExecutionContext exe_ctx(GetExecutionContextRef());
-
- if (m_byte_size == 0)
- SetByteSize(
- GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope()));
+ if (m_byte_size == 0) {
+ if (auto size =
+ GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope()))
+ SetByteSize(*size);
+ }
return m_byte_size;
}
diff --git a/lldb/source/Core/ValueObjectMemory.cpp b/lldb/source/Core/ValueObjectMemory.cpp
index c6c95ee..a289962 100644
--- a/lldb/source/Core/ValueObjectMemory.cpp
+++ b/lldb/source/Core/ValueObjectMemory.cpp
@@ -138,7 +138,9 @@
uint64_t ValueObjectMemory::GetByteSize() {
if (m_type_sp)
return m_type_sp->GetByteSize();
- return m_compiler_type.GetByteSize(nullptr);
+ if (auto size = m_compiler_type.GetByteSize(nullptr))
+ return *size;
+ return 0;
}
lldb::ValueType ValueObjectMemory::GetValueType() const {
diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index 4f52ec8..fcdd8cc 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/source/Core/ValueObjectVariable.cpp
@@ -112,7 +112,8 @@
if (!type.IsValid())
return 0;
- return type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
+ auto size = type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
+ return size ? *size : 0;
}
lldb::ValueType ValueObjectVariable::GetValueType() const {