Add data formatter for libc++ std::queue

Summary:
std::queue is just a fancy wrapper around another container, so all we
need to do is to delegate to the it.

Reviewers: jingham, EricWF

Subscribers: srhines, mgorny, lldb-commits, eugene

Differential Revision: https://reviews.llvm.org/D35666

llvm-svn: 317099
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 9ddc6b2..fb4fa5c 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -8,6 +8,7 @@
   LibCxxInitializerList.cpp
   LibCxxList.cpp
   LibCxxMap.cpp
+  LibCxxQueue.cpp
   LibCxxTuple.cpp
   LibCxxUnorderedMap.cpp
   LibCxxVector.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index e6ee40e..cc31832 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -473,6 +473,10 @@
       "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,
@@ -532,6 +536,11 @@
                 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);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index f5180d1..096f354 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -123,6 +123,9 @@
 SyntheticChildrenFrontEnd *LibcxxFunctionFrontEndCreator(CXXSyntheticChildren *,
                                                          lldb::ValueObjectSP);
 
+SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
+                                                      lldb::ValueObjectSP);
+
 SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
                                                       lldb::ValueObjectSP);
 
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
new file mode 100644
index 0000000..c4e0b66
--- /dev/null
+++ b/lldb/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;
+}