diff options
author | Adrian Prantl <aprantl@apple.com> | 2019-01-15 18:07:52 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2019-01-15 18:07:52 +0000 |
commit | d963a7c39891ae33e87500502d5199946af22bde (patch) | |
tree | 1a5d123b49e1e9e039a62b08a9011cb91560883f /lldb/source/Plugins/Language/CPlusPlus | |
parent | 5e54bc18e27b7fa2af240ff93f1771faa425c319 (diff) | |
download | bcm5719-llvm-d963a7c39891ae33e87500502d5199946af22bde.tar.gz bcm5719-llvm-d963a7c39891ae33e87500502d5199946af22bde.zip |
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
Diffstat (limited to 'lldb/source/Plugins/Language/CPlusPlus')
6 files changed, 86 insertions, 51 deletions
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index 0f6fb54e838..6a41ff84e0b 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -100,8 +100,11 @@ bool lldb_private::formatters::WCharStringSummaryProvider( if (!wchar_compiler_type) return false; - const uint32_t wchar_size = wchar_compiler_type.GetBitSize( - nullptr); // Safe to pass NULL for exe_scope here + // Safe to pass nullptr for exe_scope here. + auto size = wchar_compiler_type.GetBitSize(nullptr); + if (!size) + return false; + const uint32_t wchar_size = *size; StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); @@ -194,8 +197,11 @@ bool lldb_private::formatters::WCharSummaryProvider( if (!wchar_compiler_type) return false; - const uint32_t wchar_size = wchar_compiler_type.GetBitSize( - nullptr); // Safe to pass NULL for exe_scope here + // Safe to pass nullptr for exe_scope here. + auto size = wchar_compiler_type.GetBitSize(nullptr); + if (!size) + return false; + const uint32_t wchar_size = *size; StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); options.SetData(data); diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 5a560683f0e..af118a71d09 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -225,9 +225,14 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { m_pair_ptr = nullptr; return false; } - CompilerType pair_type(__i_->GetCompilerType().GetTypeTemplateArgument(0)); - std::string name; uint64_t bit_offset_ptr; uint32_t bitfield_bit_size_ptr; bool is_bitfield_ptr; - pair_type = pair_type.GetFieldAtIndex(0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr); + CompilerType pair_type( + __i_->GetCompilerType().GetTypeTemplateArgument(0)); + std::string name; + uint64_t bit_offset_ptr; + uint32_t bitfield_bit_size_ptr; + bool is_bitfield_ptr; + pair_type = pair_type.GetFieldAtIndex( + 0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr); if (!pair_type) { m_pair_ptr = nullptr; return false; @@ -235,27 +240,38 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS)); m_pair_ptr = nullptr; - if (addr && addr!=LLDB_INVALID_ADDRESS) { - ClangASTContext *ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem()); + if (addr && addr != LLDB_INVALID_ADDRESS) { + ClangASTContext *ast_ctx = + llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem()); if (!ast_ctx) return false; - CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(ConstString(), { - {"ptr0",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr1",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr2",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"cw",ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, - {"payload",pair_type} - }); - DataBufferSP buffer_sp(new DataBufferHeap(tree_node_type.GetByteSize(nullptr),0)); + CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( + ConstString(), + {{"ptr0", + ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr1", + ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr2", + ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, + {"payload", pair_type}}); + auto size = tree_node_type.GetByteSize(nullptr); + if (!size) + return false; + DataBufferSP buffer_sp(new DataBufferHeap(*size, 0)); ProcessSP process_sp(target_sp->GetProcessSP()); Status error; - process_sp->ReadMemory(addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), error); + process_sp->ReadMemory(addr, buffer_sp->GetBytes(), + buffer_sp->GetByteSize(), error); if (error.Fail()) return false; - DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); - auto pair_sp = CreateValueObjectFromData("pair", extractor, valobj_sp->GetExecutionContextRef(), tree_node_type); + DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(), + process_sp->GetAddressByteSize()); + auto pair_sp = CreateValueObjectFromData( + "pair", extractor, valobj_sp->GetExecutionContextRef(), + tree_node_type); if (pair_sp) - m_pair_sp = pair_sp->GetChildAtIndex(4,true); + m_pair_sp = pair_sp->GetChildAtIndex(4, true); } } } @@ -560,6 +576,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( ->GetScratchClangASTContext() ->GetBasicType(lldb::eBasicTypeWChar) .GetByteSize(nullptr); + if (!wchar_t_size) + return false; options.SetData(extractor); options.SetStream(&stream); @@ -568,7 +586,7 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( options.SetSourceSize(size); options.SetBinaryZeroIsTerminator(false); - switch (wchar_t_size) { + switch (*wchar_t_size) { case 1: StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::UTF8>( diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp index 0cdb0b26cf3..0d39e5a57cf 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp @@ -79,17 +79,22 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) { CompilerType type; ValueObjectSP chunk; // For small bitsets __first_ is not an array, but a plain size_t. - if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) - chunk = m_first->GetChildAtIndex( - idx / type.GetBitSize(ctx.GetBestExecutionContextScope()), true); - else { + if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) { + auto bit_size = type.GetBitSize(ctx.GetBestExecutionContextScope()); + if (!bit_size || *bit_size == 0) + return {}; + chunk = m_first->GetChildAtIndex(idx / *bit_size, true); + } else { type = m_first->GetCompilerType(); chunk = m_first; } if (!type || !chunk) - return ValueObjectSP(); + return {}; - size_t chunk_idx = idx % type.GetBitSize(ctx.GetBestExecutionContextScope()); + auto bit_size = type.GetBitSize(ctx.GetBestExecutionContextScope()); + if (!bit_size || *bit_size == 0) + return {}; + size_t chunk_idx = idx % *bit_size; uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx)); DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size); diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp index b000410aef8..a692c120b35 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp @@ -94,12 +94,11 @@ bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: if (!m_element_type.IsValid()) return false; - m_element_size = m_element_type.GetByteSize(nullptr); - - if (m_element_size > 0) - m_start = - m_backend.GetChildMemberWithName(g___begin_, true) - .get(); // store raw pointers or end up with a circular dependency + if (auto size = m_element_type.GetByteSize(nullptr)) { + m_element_size = *size; + // Store raw pointers or end up with a circular dependency. + m_start = m_backend.GetChildMemberWithName(g___begin_, true).get(); + } return false; } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp index c05e84fa0d3..9cde54b4f4f 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -145,14 +145,16 @@ bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() { if (!data_type_finder_sp) return false; m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType(); - m_element_size = m_element_type.GetByteSize(nullptr); - - if (m_element_size > 0) { - // store raw pointers or end up with a circular dependency - m_start = - m_backend.GetChildMemberWithName(ConstString("__begin_"), true).get(); - m_finish = - m_backend.GetChildMemberWithName(ConstString("__end_"), true).get(); + if (auto size = m_element_type.GetByteSize(nullptr)) { + m_element_size = *size; + + if (m_element_size > 0) { + // store raw pointers or end up with a circular dependency + m_start = + m_backend.GetChildMemberWithName(ConstString("__begin_"), true).get(); + m_finish = + m_backend.GetChildMemberWithName(ConstString("__end_"), true).get(); + } } return false; } @@ -192,27 +194,29 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex( if (iter != end) return iter->second; if (idx >= m_count) - return ValueObjectSP(); + return {}; if (m_base_data_address == 0 || m_count == 0) - return ValueObjectSP(); + return {}; if (!m_bool_type) - return ValueObjectSP(); + return {}; size_t byte_idx = (idx >> 3); // divide by 8 to get byte index size_t bit_index = (idx & 7); // efficient idx % 8 for bit index lldb::addr_t byte_location = m_base_data_address + byte_idx; ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP()); if (!process_sp) - return ValueObjectSP(); + return {}; uint8_t byte = 0; uint8_t mask = 0; Status err; size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err); if (err.Fail() || bytes_read == 0) - return ValueObjectSP(); + return {}; mask = 1 << bit_index; bool bit_set = ((byte & mask) != 0); - DataBufferSP buffer_sp( - new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0)); + auto size = m_bool_type.GetByteSize(nullptr); + if (!size) + return {}; + DataBufferSP buffer_sp(new DataBufferHeap(*size, 0)); if (bit_set && buffer_sp && buffer_sp->GetBytes()) { // regardless of endianness, anything non-zero is true *(buffer_sp->GetBytes()) = 1; diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 2827feb9741..f25391f9512 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -297,8 +297,11 @@ bool lldb_private::formatters::LibStdcppWStringSummaryProvider( if (!wchar_compiler_type) return false; - const uint32_t wchar_size = wchar_compiler_type.GetBitSize( - nullptr); // Safe to pass NULL for exe_scope here + // Safe to pass nullptr for exe_scope here. + auto size = wchar_compiler_type.GetBitSize(nullptr); + if (!size) + return false; + const uint32_t wchar_size = *size; StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); Status error; |