diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:12:36 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:12:36 +0000 | 
| commit | ef5d0b5e97ec8e6fa395d377b09aa7755e345b4f (patch) | |
| tree | 27916256fdeeb57d10d2f3d6948be5d71a703215 /source/Plugins/Language/CPlusPlus | |
| parent | 76e0736e7fcfeb179779e49c05604464b1ccd704 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/Language/CPlusPlus')
14 files changed, 499 insertions, 110 deletions
diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt index 8f769c499987f..180440a244a4a 100644 --- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt +++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt @@ -5,9 +5,12 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN    CxxStringTypes.cpp    LibCxx.cpp    LibCxxAtomic.cpp +  LibCxxBitset.cpp    LibCxxInitializerList.cpp    LibCxxList.cpp    LibCxxMap.cpp +  LibCxxQueue.cpp +  LibCxxTuple.cpp    LibCxxUnorderedMap.cpp    LibCxxVector.cpp    LibStdcpp.cpp diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 1ae9418e4d9c0..51ed88065c84d 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -422,12 +422,24 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {    AddCXXSynthetic(        cpp_category_sp, +      lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator, +      "libc++ std::bitset synthetic children", +      ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"), stl_synth_flags, +      true); +  AddCXXSynthetic( +      cpp_category_sp,        lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,        "libc++ std::vector synthetic children",        ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags,        true);    AddCXXSynthetic(        cpp_category_sp, +      lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator, +      "libc++ std::forward_list synthetic children", +      ConstString("^std::__(ndk)?1::forward_list<.+>(( )?&)?$"), +      stl_synth_flags, true); +  AddCXXSynthetic( +      cpp_category_sp,        lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,        "libc++ std::list synthetic children",        ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true); @@ -467,6 +479,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {        "libc++ std::initializer_list synthetic children",        ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,        true); +  AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator, +                  "libc++ std::queue synthetic children", +                  ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"), +                  stl_synth_flags, true); +  AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator, +                  "libc++ std::tuple synthetic children", +                  ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_synth_flags, +                  true);    AddCXXSynthetic(        cpp_category_sp,        lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, @@ -497,12 +517,22 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {    stl_summary_flags.SetSkipPointers(false);    AddCXXSummary(cpp_category_sp,                  lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::bitset summary provider", +                ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider,                  "libc++ std::vector summary provider",                  ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"),                  stl_summary_flags, true);    AddCXXSummary(cpp_category_sp,                  lldb_private::formatters::LibcxxContainerSummaryProvider,                  "libc++ std::list summary provider", +                ConstString("^std::__(ndk)?1::forward_list<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::list summary provider",                  ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"),                  stl_summary_flags, true);    AddCXXSummary(cpp_category_sp, @@ -517,6 +547,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {                  stl_summary_flags, true);    AddCXXSummary(cpp_category_sp,                  lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::queue summary provider", +                ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider,                  "libc++ std::set summary provider",                  ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"),                  stl_summary_flags, true); @@ -535,6 +570,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {        "libc++ std::unordered containers summary provider",        ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"),        stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, LibcxxContainerSummaryProvider, +                "libc++ std::tuple summary provider", +                ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_summary_flags, +                true);    AddCXXSummary(        cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider,        "libc++ std::atomic summary provider", diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp index 88bdd68ff3011..aebea6ae3569b 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp @@ -628,7 +628,7 @@ static const clang::LangOptions &GetLangOptions() {      g_options.CPlusPlus = true;      g_options.CPlusPlus11 = true;      g_options.CPlusPlus14 = true; -    g_options.CPlusPlus1z = true; +    g_options.CPlusPlus17 = true;    });    return g_options;  } diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 11245e1310b77..f6d1f18cb596b 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -153,12 +153,11 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {                       .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)); +      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) { diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.h b/source/Plugins/Language/CPlusPlus/LibCxx.h index 7610212b4245a..3f6e0d6e14d7f 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -93,6 +93,10 @@ private:  };  SyntheticChildrenFrontEnd * +LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                     lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd *  LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,                                          lldb::ValueObjectSP); @@ -105,6 +109,10 @@ LibcxxStdListSyntheticFrontEndCreator(CXXSyntheticChildren *,                                        lldb::ValueObjectSP);  SyntheticChildrenFrontEnd * +LibcxxStdForwardListSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                             lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd *  LibcxxStdMapSyntheticFrontEndCreator(CXXSyntheticChildren *,                                       lldb::ValueObjectSP); @@ -119,6 +127,12 @@ LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *,  SyntheticChildrenFrontEnd *LibcxxFunctionFrontEndCreator(CXXSyntheticChildren *,                                                           lldb::ValueObjectSP); +SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *, +                                                      lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *, +                                                      lldb::ValueObjectSP); +  } // namespace formatters  } // namespace lldb_private diff --git a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp new file mode 100644 index 0000000000000..0cdb0b26cf3bd --- /dev/null +++ b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp @@ -0,0 +1,107 @@ +//===-- LibCxxBitset.cpp ----------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibCxx.h" +#include "lldb/DataFormatters/FormattersHelpers.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +namespace { + +class BitsetFrontEnd : public SyntheticChildrenFrontEnd { +public: +  BitsetFrontEnd(ValueObject &valobj); + +  size_t GetIndexOfChildWithName(const ConstString &name) override { +    return formatters::ExtractIndexFromString(name.GetCString()); +  } + +  bool MightHaveChildren() override { return true; } +  bool Update() override; +  size_t CalculateNumChildren() override { return m_elements.size(); } +  ValueObjectSP GetChildAtIndex(size_t idx) override; + +private: +  std::vector<ValueObjectSP> m_elements; +  ValueObjectSP m_first; +  CompilerType m_bool_type; +  ByteOrder m_byte_order = eByteOrderInvalid; +  uint8_t m_byte_size = 0; +}; +} // namespace + +BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj) +    : SyntheticChildrenFrontEnd(valobj) { +  m_bool_type = valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeBool); +  if (auto target_sp = m_backend.GetTargetSP()) { +    m_byte_order = target_sp->GetArchitecture().GetByteOrder(); +    m_byte_size = target_sp->GetArchitecture().GetAddressByteSize(); +    Update(); +  } +} + +bool BitsetFrontEnd::Update() { +  m_elements.clear(); +  m_first.reset(); + +  TargetSP target_sp = m_backend.GetTargetSP(); +  if (!target_sp) +    return false; +  size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay(); + +  size_t size = 0; +  if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0)) +    size = arg->value.getLimitedValue(capping_size); + +  m_elements.assign(size, ValueObjectSP()); + +  m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true); +  return false; +} + +ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) { +  if (idx >= m_elements.size() || !m_first) +    return ValueObjectSP(); + +  if (m_elements[idx]) +    return m_elements[idx]; + +  ExecutionContext ctx = m_backend.GetExecutionContextRef().Lock(false); +  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 { +    type = m_first->GetCompilerType(); +    chunk = m_first; +  } +  if (!type || !chunk) +    return ValueObjectSP(); + +  size_t chunk_idx = idx % type.GetBitSize(ctx.GetBestExecutionContextScope()); +  uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx)); +  DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size); + +  m_elements[idx] = CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(), +                                              data, ctx, m_bool_type); + +  return m_elements[idx]; +} + +SyntheticChildrenFrontEnd *formatters::LibcxxBitsetSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  if (valobj_sp) +    return new BitsetFrontEnd(*valobj_sp); +  return nullptr; +} diff --git a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp index 4e839532afb79..5823f6f3e0382 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp @@ -94,9 +94,8 @@ bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::    m_start = nullptr;    m_num_elements = 0; -  lldb::TemplateArgumentKind kind; -  m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind); -  if (kind != lldb::eTemplateArgumentKindType || !m_element_type.IsValid()) +  m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0); +  if (!m_element_type.IsValid())      return false;    m_element_size = m_element_type.GetByteSize(nullptr); diff --git a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp index 56d8edaba72ac..6407ae129ad7d 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp @@ -114,58 +114,90 @@ private:    ListEntry m_entry;  }; -} // end anonymous namespace - -namespace lldb_private { -namespace formatters { -class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +class AbstractListFrontEnd : public SyntheticChildrenFrontEnd {  public: -  LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); +  size_t GetIndexOfChildWithName(const ConstString &name) override { +    return ExtractIndexFromString(name.GetCString()); +  } +  bool MightHaveChildren() override { return true; } +  bool Update() override; -  ~LibcxxStdListSyntheticFrontEnd() override = default; +protected: +  AbstractListFrontEnd(ValueObject &valobj) +      : SyntheticChildrenFrontEnd(valobj) {} -  size_t CalculateNumChildren() override; +  size_t m_count; +  ValueObject *m_head; -  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; +  static constexpr bool g_use_loop_detect = true; +  size_t m_loop_detected; // The number of elements that have had loop detection +                          // run over them. +  ListEntry m_slow_runner; // Used for loop detection +  ListEntry m_fast_runner; // Used for loop detection + +  size_t m_list_capping_size; +  CompilerType m_element_type; +  std::map<size_t, ListIterator> m_iterators; + +  bool HasLoop(size_t count); +  ValueObjectSP GetItem(size_t idx); +}; +class ForwardListFrontEnd : public AbstractListFrontEnd { +public: +  ForwardListFrontEnd(ValueObject &valobj); + +  size_t CalculateNumChildren() override; +  ValueObjectSP GetChildAtIndex(size_t idx) override;    bool Update() override; +}; -  bool MightHaveChildren() override; +class ListFrontEnd : public AbstractListFrontEnd { +public: +  ListFrontEnd(lldb::ValueObjectSP valobj_sp); -  size_t GetIndexOfChildWithName(const ConstString &name) override; +  ~ListFrontEnd() override = default; -private: -  bool HasLoop(size_t count); +  size_t CalculateNumChildren() override; -  size_t m_list_capping_size; -  static const bool g_use_loop_detect = true; +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; -  size_t m_loop_detected; // The number of elements that have had loop detection -                          // run over them. -  ListEntry m_slow_runner; // Used for loop detection -  ListEntry m_fast_runner; // Used for loop detection +  bool Update() override; +private:    lldb::addr_t m_node_address; -  ValueObject *m_head;    ValueObject *m_tail; -  CompilerType m_element_type; -  size_t m_count; -  std::map<size_t, ListIterator> m_iterators;  }; -} // namespace formatters -} // namespace lldb_private - -lldb_private::formatters::LibcxxStdListSyntheticFrontEnd:: -    LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) -    : SyntheticChildrenFrontEnd(*valobj_sp), m_list_capping_size(0), -      m_loop_detected(0), m_node_address(), m_head(nullptr), m_tail(nullptr), -      m_element_type(), m_count(UINT32_MAX), m_iterators() { -  if (valobj_sp) -    Update(); + +} // end anonymous namespace + +bool AbstractListFrontEnd::Update() { +  m_loop_detected = 0; +  m_count = UINT32_MAX; +  m_head = nullptr; +  m_list_capping_size = 0; +  m_slow_runner.SetEntry(nullptr); +  m_fast_runner.SetEntry(nullptr); +  m_iterators.clear(); + +  if (m_backend.GetTargetSP()) +    m_list_capping_size = +        m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); +  if (m_list_capping_size == 0) +    m_list_capping_size = 255; + +  CompilerType list_type = m_backend.GetCompilerType(); +  if (list_type.IsReferenceType()) +    list_type = list_type.GetNonReferenceType(); + +  if (list_type.GetNumTemplateArguments() == 0) +    return false; +  m_element_type = list_type.GetTypeTemplateArgument(0); + +  return false;  } -bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop( -    size_t count) { +bool AbstractListFrontEnd::HasLoop(size_t count) {    if (!g_use_loop_detect)      return false;    // don't bother checking for a loop if we won't actually need to jump nodes @@ -201,8 +233,105 @@ bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop(    return m_slow_runner == m_fast_runner;  } -size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd:: -    CalculateNumChildren() { +ValueObjectSP AbstractListFrontEnd::GetItem(size_t idx) { +  size_t advance = idx; +  ListIterator current(m_head); +  if (idx > 0) { +    auto cached_iterator = m_iterators.find(idx - 1); +    if (cached_iterator != m_iterators.end()) { +      current = cached_iterator->second; +      advance = 1; +    } +  } +  ValueObjectSP value_sp = current.advance(advance); +  m_iterators[idx] = current; +  return value_sp; +} + +ForwardListFrontEnd::ForwardListFrontEnd(ValueObject &valobj) +    : AbstractListFrontEnd(valobj) { +  Update(); +} + +size_t ForwardListFrontEnd::CalculateNumChildren() { +  if (m_count != UINT32_MAX) +    return m_count; + +  ListEntry current(m_head); +  m_count = 0; +  while (current && m_count < m_list_capping_size) { +    ++m_count; +    current = current.next(); +  } +  return m_count; +} + +ValueObjectSP ForwardListFrontEnd::GetChildAtIndex(size_t idx) { +  if (idx >= CalculateNumChildren()) +    return nullptr; + +  if (!m_head) +    return nullptr; + +  if (HasLoop(idx + 1)) +    return nullptr; + +  ValueObjectSP current_sp = GetItem(idx); +  if (!current_sp) +    return nullptr; + +  current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child +  if (!current_sp) +    return nullptr; + +  // we need to copy current_sp into a new object otherwise we will end up with +  // all items named __value_ +  DataExtractor data; +  Status error; +  current_sp->GetData(data, error); +  if (error.Fail()) +    return nullptr; + +  return CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(), data, +                                   m_backend.GetExecutionContextRef(), +                                   m_element_type); +} + +static ValueObjectSP GetValueOfCompressedPair(ValueObject &pair) { +  ValueObjectSP value = pair.GetChildMemberWithName(ConstString("__value_"), true); +  if (! value) { +    // pre-r300140 member name +    value = pair.GetChildMemberWithName(ConstString("__first_"), true); +  } +  return value; +} + +bool ForwardListFrontEnd::Update() { +  AbstractListFrontEnd::Update(); + +  Status err; +  ValueObjectSP backend_addr(m_backend.AddressOf(err)); +  if (err.Fail() || !backend_addr) +    return false; + +  ValueObjectSP impl_sp( +      m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true)); +  if (!impl_sp) +    return false; +  impl_sp = GetValueOfCompressedPair(*impl_sp); +  if (!impl_sp) +    return false; +  m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); +  return false; +} + +ListFrontEnd::ListFrontEnd(lldb::ValueObjectSP valobj_sp) +    : AbstractListFrontEnd(*valobj_sp), m_node_address(), m_tail(nullptr) { +  if (valobj_sp) +    Update(); +} + +size_t ListFrontEnd::CalculateNumChildren() {    if (m_count != UINT32_MAX)      return m_count;    if (!m_head || !m_tail || m_node_address == 0) @@ -210,10 +339,9 @@ size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::    ValueObjectSP size_alloc(        m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));    if (size_alloc) { -    ValueObjectSP first( -        size_alloc->GetChildMemberWithName(ConstString("__first_"), true)); -    if (first) { -      m_count = first->GetValueAsUnsigned(UINT32_MAX); +    ValueObjectSP value = GetValueOfCompressedPair(*size_alloc); +    if (value) { +      m_count = value->GetValueAsUnsigned(UINT32_MAX);      }    }    if (m_count != UINT32_MAX) { @@ -239,9 +367,7 @@ size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::    }  } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex( -    size_t idx) { +lldb::ValueObjectSP ListFrontEnd::GetChildAtIndex(size_t idx) {    static ConstString g_value("__value_");    static ConstString g_next("__next_"); @@ -254,23 +380,10 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(    if (HasLoop(idx + 1))      return lldb::ValueObjectSP(); -  size_t actual_advance = idx; - -  ListIterator current(m_head); -  if (idx > 0) { -    auto cached_iterator = m_iterators.find(idx - 1); -    if (cached_iterator != m_iterators.end()) { -      current = cached_iterator->second; -      actual_advance = 1; -    } -  } - -  ValueObjectSP current_sp(current.advance(actual_advance)); +  ValueObjectSP current_sp = GetItem(idx);    if (!current_sp)      return lldb::ValueObjectSP(); -  m_iterators[idx] = current; -    current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child    if (!current_sp)      return lldb::ValueObjectSP(); @@ -303,23 +416,13 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(                                     m_element_type);  } -bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() { -  m_iterators.clear(); -  m_head = m_tail = nullptr; +bool ListFrontEnd::Update() { +  AbstractListFrontEnd::Update(); +  m_tail = nullptr;    m_node_address = 0; -  m_count = UINT32_MAX; -  m_loop_detected = 0; -  m_slow_runner.SetEntry(nullptr); -  m_fast_runner.SetEntry(nullptr);    Status err;    ValueObjectSP backend_addr(m_backend.AddressOf(err)); -  m_list_capping_size = 0; -  if (m_backend.GetTargetSP()) -    m_list_capping_size = -        m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); -  if (m_list_capping_size == 0) -    m_list_capping_size = 255;    if (err.Fail() || !backend_addr)      return false;    m_node_address = backend_addr->GetValueAsUnsigned(0); @@ -329,31 +432,18 @@ bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() {        m_backend.GetChildMemberWithName(ConstString("__end_"), true));    if (!impl_sp)      return false; -  CompilerType list_type = m_backend.GetCompilerType(); -  if (list_type.IsReferenceType()) -    list_type = list_type.GetNonReferenceType(); - -  if (list_type.GetNumTemplateArguments() == 0) -    return false; -  lldb::TemplateArgumentKind kind; -  m_element_type = list_type.GetTemplateArgument(0, kind);    m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();    m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get();    return false;  } -bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd:: -    MightHaveChildren() { -  return true; -} - -size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd:: -    GetIndexOfChildWithName(const ConstString &name) { -  return ExtractIndexFromString(name.GetCString()); +SyntheticChildrenFrontEnd *formatters::LibcxxStdListSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new ListFrontEnd(valobj_sp) : nullptr);  }  SyntheticChildrenFrontEnd * -lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator( +formatters::LibcxxStdForwardListSyntheticFrontEndCreator(      CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { -  return (valobj_sp ? new LibcxxStdListSyntheticFrontEnd(valobj_sp) : nullptr); +  return valobj_sp ? new ForwardListFrontEnd(*valobj_sp) : nullptr;  } diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index b7215dbcbb485..be96a6d95bcd5 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -268,13 +268,12 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {      m_element_type = deref->GetCompilerType();      return true;    } -  lldb::TemplateArgumentKind kind;    deref = m_backend.GetChildAtNamePath({g_tree_, g_pair3});    if (!deref)      return false; -  m_element_type = -      deref->GetCompilerType().GetTemplateArgument(1, kind).GetTemplateArgument( -          1, kind); +  m_element_type = deref->GetCompilerType() +                       .GetTypeTemplateArgument(1) +                       .GetTypeTemplateArgument(1);    if (m_element_type) {      std::string name;      uint64_t bit_offset_ptr; @@ -285,7 +284,7 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {      m_element_type = m_element_type.GetTypedefedType();      return m_element_type.IsValid();    } else { -    m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind); +    m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0);      return m_element_type.IsValid();    }  } diff --git a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp new file mode 100644 index 0000000000000..c4e0b66d4272e --- /dev/null +++ b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp @@ -0,0 +1,61 @@ +//===-- LibCxxQueue.cpp -----------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibCxx.h" +#include "lldb/DataFormatters/FormattersHelpers.h" + +using namespace lldb; +using namespace lldb_private; + +namespace { + +class QueueFrontEnd : public SyntheticChildrenFrontEnd { +public: +  QueueFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { +    Update(); +  } + +  size_t GetIndexOfChildWithName(const ConstString &name) override { +    return m_container_sp ? m_container_sp->GetIndexOfChildWithName(name) +                          : UINT32_MAX; +  } + +  bool MightHaveChildren() override { return true; } +  bool Update() override; + +  size_t CalculateNumChildren() override { +    return m_container_sp ? m_container_sp->GetNumChildren() : 0; +  } + +  ValueObjectSP GetChildAtIndex(size_t idx) override { +    return m_container_sp ? m_container_sp->GetChildAtIndex(idx, true) +                          : nullptr; +  } + +private: +  ValueObjectSP m_container_sp; +}; +} // namespace + +bool QueueFrontEnd::Update() { +  m_container_sp.reset(); +  ValueObjectSP c_sp = m_backend.GetChildMemberWithName(ConstString("c"), true); +  if (!c_sp) +    return false; +  m_container_sp = c_sp->GetSyntheticValue(); +  return false; +} + +SyntheticChildrenFrontEnd * +formatters::LibcxxQueueFrontEndCreator(CXXSyntheticChildren *, +                                       lldb::ValueObjectSP valobj_sp) { +  if (valobj_sp) +    return new QueueFrontEnd(*valobj_sp); +  return nullptr; +} diff --git a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp new file mode 100644 index 0000000000000..9b412a12f532f --- /dev/null +++ b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp @@ -0,0 +1,83 @@ +//===-- LibCxxTuple.cpp -----------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibCxx.h" +#include "lldb/DataFormatters/FormattersHelpers.h" + +using namespace lldb; +using namespace lldb_private; + +namespace { + +class TupleFrontEnd: public SyntheticChildrenFrontEnd { +public: +  TupleFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { +    Update(); +  } + +  size_t GetIndexOfChildWithName(const ConstString &name) override { +    return formatters::ExtractIndexFromString(name.GetCString()); +  } + +  bool MightHaveChildren() override { return true; } +  bool Update() override; +  size_t CalculateNumChildren() override { return m_elements.size(); } +  ValueObjectSP GetChildAtIndex(size_t idx) override; + +private: +  std::vector<ValueObjectSP> m_elements; +  ValueObjectSP m_base_sp; +}; +} + +bool TupleFrontEnd::Update() { +  m_elements.clear(); +  m_base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true); +  if (! m_base_sp) { +    // Pre r304382 name of the base element. +    m_base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true); +  } +  if (! m_base_sp) +    return false; +  m_elements.assign(m_base_sp->GetCompilerType().GetNumDirectBaseClasses(), +                    ValueObjectSP()); +  return false; +} + +ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) { +  if (idx >= m_elements.size()) +    return ValueObjectSP(); +  if (!m_base_sp) +    return ValueObjectSP(); +  if (m_elements[idx]) +    return m_elements[idx]; + +  CompilerType holder_type = +      m_base_sp->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr); +  if (!holder_type) +    return ValueObjectSP(); +  ValueObjectSP holder_sp = m_base_sp->GetChildAtIndex(idx, true); +  if (!holder_sp) +    return ValueObjectSP(); + +  ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true); +  if (elem_sp) +    m_elements[idx] = +        elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())); + +  return m_elements[idx]; +} + +SyntheticChildrenFrontEnd * +formatters::LibcxxTupleFrontEndCreator(CXXSyntheticChildren *, +                                       lldb::ValueObjectSP valobj_sp) { +  if (valobj_sp) +    return new TupleFrontEnd(*valobj_sp); +  return nullptr; +} diff --git a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp index 190b5f64381ea..0f1c2537d651e 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -121,11 +121,10 @@ lldb::ValueObjectSP lldb_private::formatters::          if (!first_sp)            return nullptr;          m_element_type = first_sp->GetCompilerType(); -        lldb::TemplateArgumentKind kind; -        m_element_type = m_element_type.GetTemplateArgument(0, kind); +        m_element_type = m_element_type.GetTypeTemplateArgument(0);          m_element_type = m_element_type.GetPointeeType();          m_node_type = m_element_type; -        m_element_type = m_element_type.GetTemplateArgument(0, kind); +        m_element_type = m_element_type.GetTypeTemplateArgument(0);          std::string name;          m_element_type =              m_element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr); diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp index 6f601c9f6ccbf..711130639cd2f 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -290,8 +290,7 @@ lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator(    CompilerType type = valobj_sp->GetCompilerType();    if (!type.IsValid() || type.GetNumTemplateArguments() == 0)      return nullptr; -  TemplateArgumentKind kind; -  CompilerType arg_type = type.GetTemplateArgument(0, kind); +  CompilerType arg_type = type.GetTypeTemplateArgument(0);    if (arg_type.GetTypeName() == ConstString("bool"))      return new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp);    return new LibcxxStdVectorSyntheticFrontEnd(valobj_sp); diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index e3018a1884be1..3e2b7159f8944 100644 --- a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -117,11 +117,8 @@ bool LibstdcppMapIteratorSyntheticFrontEnd::Update() {    CompilerType my_type(valobj_sp->GetCompilerType());    if (my_type.GetNumTemplateArguments() >= 1) { -    TemplateArgumentKind kind; -    CompilerType pair_type = my_type.GetTemplateArgument(0, kind); -    if (kind != eTemplateArgumentKindType && -        kind != eTemplateArgumentKindTemplate && -        kind != eTemplateArgumentKindTemplateExpansion) +    CompilerType pair_type = my_type.GetTypeTemplateArgument(0); +    if (!pair_type)        return false;      m_pair_type = pair_type;    } else  | 
