summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEnrico Granata <egranata@apple.com>2016-09-28 22:53:16 +0000
committerEnrico Granata <egranata@apple.com>2016-09-28 22:53:16 +0000
commitae1ba73aeb538d26e44c6e66209a6ef49fd8a1b9 (patch)
tree156417a207fecf6d9426ca6cef9c3d47d6b0ff63
parentb17840de33e316a633749bab2c97c470d93ce933 (diff)
downloadbcm5719-llvm-ae1ba73aeb538d26e44c6e66209a6ef49fd8a1b9.tar.gz
bcm5719-llvm-ae1ba73aeb538d26e44c6e66209a6ef49fd8a1b9.zip
Fix an issue where libc++ changed the type information we get for std::map::iterator, rendering LLDB unable to display elements vended by an iterator
Fixes <rdar://problem/28237521> llvm-svn: 282648
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py6
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp14
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp69
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxx.h1
4 files changed, 75 insertions, 15 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
index cbcdc2ce739..5d23fcef04c 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
@@ -65,9 +65,9 @@ class LibcxxIteratorDataFormatterTestCase(TestBase):
self.expect(
'frame variable iimI',
substrs=[
- 'first = 0',
- 'second = 12'])
- self.expect('expr iimI', substrs=['first = 0', 'second = 12'])
+ 'first = 43981',
+ 'second = 61681'])
+ self.expect('expr iimI', substrs=['first = 43981', 'second = 61681'])
self.expect(
'frame variable simI',
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
index 97b37851f53..058a79317d1 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
@@ -20,23 +20,23 @@ typedef string_vector::iterator svter;
int main()
{
- intint_map iim;
- iim[0] = 12;
-
+ intint_map iim;
+ iim[0xABCD] = 0xF0F1;
+
strint_map sim;
sim["world"] = 42;
-
+
int_vector iv;
iv.push_back(3);
-
+
string_vector sv;
sv.push_back("hello");
iimter iimI = iim.begin();
simter simI = sim.begin();
-
+
ivter ivI = iv.begin();
svter svI = sv.begin();
- return 0; // Set break point at this line.
+ return 0; // Set break point at this line.
} \ No newline at end of file
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 74f4c5c3ac4..7303ae50f5b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -27,6 +27,7 @@
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ProcessStructReader.h"
using namespace lldb;
using namespace lldb_private;
@@ -247,12 +248,15 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator(
lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr() {
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() {
if (valobj_sp)
Update();
}
bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
+ m_pair_sp.reset();
+ m_pair_ptr = nullptr;
+
ValueObjectSP valobj_sp = m_backend.GetSP();
if (!valobj_sp)
return false;
@@ -264,7 +268,9 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
if (!valobj_sp)
return false;
-
+
+ static ConstString g___i_("__i_");
+
// this must be a ValueObject* because it is a child of the ValueObject we are
// producing children for
// it if were a ValueObjectSP, we would end up with a loop (iterator ->
@@ -281,6 +287,57 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
SyntheticChildrenTraversal::None),
nullptr)
.get();
+
+ if (!m_pair_ptr) {
+ m_pair_ptr = valobj_sp->GetValueForExpressionPath(".__i_.__ptr_", nullptr, nullptr, nullptr,
+ ValueObject::GetValueForExpressionPathOptions()
+ .DontCheckDotVsArrowSyntax()
+ .SetSyntheticChildrenTraversal(
+ ValueObject::GetValueForExpressionPathOptions::
+ SyntheticChildrenTraversal::None),
+ nullptr)
+ .get();
+ if (m_pair_ptr) {
+ auto __i_(valobj_sp->GetChildMemberWithName(g___i_, true));
+ lldb::TemplateArgumentKind kind;
+ if (!__i_) {
+ m_pair_ptr = nullptr;
+ return false;
+ }
+ CompilerType pair_type(__i_->GetCompilerType().GetTemplateArgument(0, kind));
+ 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;
+ }
+
+ 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 (!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));
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ Error 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);
+ if (pair_sp)
+ m_pair_sp = pair_sp->GetChildAtIndex(4,true);
+ }
+ }
+ }
return false;
}
@@ -293,9 +350,11 @@ size_t lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
lldb::ValueObjectSP
lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetChildAtIndex(
size_t idx) {
- if (!m_pair_ptr)
- return lldb::ValueObjectSP();
- return m_pair_ptr->GetChildAtIndex(idx, true);
+ if (m_pair_ptr)
+ return m_pair_ptr->GetChildAtIndex(idx, true);
+ if (m_pair_sp)
+ return m_pair_sp->GetChildAtIndex(idx, true);
+ return lldb::ValueObjectSP();
}
bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index d34efafa7c6..a8638513376 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -81,6 +81,7 @@ public:
private:
ValueObject *m_pair_ptr;
+ lldb::ValueObjectSP m_pair_sp;
};
SyntheticChildrenFrontEnd *
OpenPOWER on IntegriCloud