diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 | 
| commit | e81d9d49145e432d917eea3a70d2ae74dcad1d89 (patch) | |
| tree | 9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Plugins/Language/CPlusPlus/LibCxxVector.cpp | |
| parent | 85d8ef8f1f0e0e063a8571944302be2d2026f823 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/Language/CPlusPlus/LibCxxVector.cpp')
| -rw-r--r-- | source/Plugins/Language/CPlusPlus/LibCxxVector.cpp | 159 | 
1 files changed, 159 insertions, 0 deletions
| diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp new file mode 100644 index 000000000000..9fb4f48e9090 --- /dev/null +++ b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -0,0 +1,159 @@ +//===-- LibCxxVector.cpp ----------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "LibCxx.h" + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/DataFormatters/FormattersHelpers.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +namespace lldb_private { +    namespace formatters { +        class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd +        { +        public: +            LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); + +            ~LibcxxStdVectorSyntheticFrontEnd() override; + +            size_t +            CalculateNumChildren() override; +             +            lldb::ValueObjectSP +            GetChildAtIndex(size_t idx) override; +             +            bool +            Update() override; +             +            bool +            MightHaveChildren() override; +             +            size_t +            GetIndexOfChildWithName(const ConstString &name) override; + +        private: +            ValueObject* m_start; +            ValueObject* m_finish; +            CompilerType m_element_type; +            uint32_t m_element_size; +            std::map<size_t,lldb::ValueObjectSP> m_children; +        }; +    } // namespace formatters +} // namespace lldb_private + +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : +SyntheticChildrenFrontEnd(*valobj_sp.get()), +m_start(NULL), +m_finish(NULL), +m_element_type(), +m_element_size(0), +m_children() +{ +    if (valobj_sp) +        Update(); +} + +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd() +{ +    // these need to stay around because they are child objects who will follow their parent's life cycle +    // delete m_start; +    // delete m_finish; +} + +size_t +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren () +{ +    if (!m_start || !m_finish) +        return 0; +    uint64_t start_val = m_start->GetValueAsUnsigned(0); +    uint64_t finish_val = m_finish->GetValueAsUnsigned(0); +     +    if (start_val == 0 || finish_val == 0) +        return 0; +     +    if (start_val >= finish_val) +        return 0; +     +    size_t num_children = (finish_val - start_val); +    if (num_children % m_element_size) +        return 0; +    return num_children/m_element_size; +} + +lldb::ValueObjectSP +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx) +{ +    if (!m_start || !m_finish) +        return lldb::ValueObjectSP(); +     +    auto cached = m_children.find(idx); +    if (cached != m_children.end()) +        return cached->second; +     +    uint64_t offset = idx * m_element_size; +    offset = offset + m_start->GetValueAsUnsigned(0); +    StreamString name; +    name.Printf("[%" PRIu64 "]", (uint64_t)idx); +    ValueObjectSP child_sp = CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type); +    m_children[idx] = child_sp; +    return child_sp; +} + +bool +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() +{ +    m_start = m_finish = NULL; +    m_children.clear(); +    ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true)); +    if (!data_type_finder_sp) +        return false; +    data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true); +    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(); +    } +    return false; +} + +bool +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren () +{ +    return true; +} + +size_t +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) +{ +    if (!m_start || !m_finish) +        return UINT32_MAX; +    return ExtractIndexFromString(name.GetCString()); +} + +lldb_private::SyntheticChildrenFrontEnd* +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) +{ +    if (!valobj_sp) +        return NULL; +    return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp)); +} | 
