Skip to content

Commit e0d5184

Browse files
committed
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
1 parent 778810e commit e0d5184

File tree

7 files changed

+134
-0
lines changed

7 files changed

+134
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
LEVEL = ../../../../../make
2+
3+
CXX_SOURCES := main.cpp
4+
5+
USE_LIBCPP := 1
6+
include $(LEVEL)/Makefile.rules
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""
2+
Test lldb data formatter subsystem.
3+
"""
4+
5+
from __future__ import print_function
6+
7+
8+
import lldb
9+
from lldbsuite.test.decorators import *
10+
from lldbsuite.test.lldbtest import *
11+
from lldbsuite.test import lldbutil
12+
13+
14+
class TestDataFormatterLibcxxQueue(TestBase):
15+
16+
mydir = TestBase.compute_mydir(__file__)
17+
18+
def setUp(self):
19+
TestBase.setUp(self)
20+
ns = 'ndk' if lldbplatformutil.target_is_android() else ''
21+
self.namespace = 'std::__' + ns + '1'
22+
23+
def check_variable(self, name):
24+
var = self.frame().FindVariable(name)
25+
self.assertTrue(var.IsValid())
26+
27+
queue = self.namespace + '::queue'
28+
self.assertTrue(queue in var.GetTypeName())
29+
self.assertEqual(var.GetNumChildren(), 5)
30+
for i in range(5):
31+
ch = var.GetChildAtIndex(i)
32+
self.assertTrue(ch.IsValid())
33+
self.assertEqual(ch.GetValueAsSigned(), i+1)
34+
35+
@add_test_categories(["libc++"])
36+
def test(self):
37+
"""Test that std::queue is displayed correctly"""
38+
self.build()
39+
lldbutil.run_to_source_breakpoint(self, '// break here',
40+
lldb.SBFileSpec("main.cpp", False))
41+
42+
self.check_variable('q1')
43+
self.check_variable('q2')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <queue>
2+
#include <vector>
3+
4+
using namespace std;
5+
6+
int main() {
7+
queue<int> q1{{1,2,3,4,5}};
8+
queue<int, std::vector<int>> q2{{1,2,3,4,5}};
9+
int ret = q1.size() + q2.size(); // break here
10+
return ret;
11+
}

lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
88
LibCxxInitializerList.cpp
99
LibCxxList.cpp
1010
LibCxxMap.cpp
11+
LibCxxQueue.cpp
1112
LibCxxTuple.cpp
1213
LibCxxUnorderedMap.cpp
1314
LibCxxVector.cpp

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
473473
"libc++ std::initializer_list synthetic children",
474474
ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,
475475
true);
476+
AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
477+
"libc++ std::queue synthetic children",
478+
ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"),
479+
stl_synth_flags, true);
476480
AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
477481
"libc++ std::tuple synthetic children",
478482
ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_synth_flags,
@@ -530,6 +534,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
530534
"libc++ std::deque summary provider",
531535
ConstString("^std::__(ndk)?1::deque<.+>(( )?&)?$"),
532536
stl_summary_flags, true);
537+
AddCXXSummary(cpp_category_sp,
538+
lldb_private::formatters::LibcxxContainerSummaryProvider,
539+
"libc++ std::queue summary provider",
540+
ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"),
541+
stl_summary_flags, true);
533542
AddCXXSummary(cpp_category_sp,
534543
lldb_private::formatters::LibcxxContainerSummaryProvider,
535544
"libc++ std::set summary provider",

lldb/source/Plugins/Language/CPlusPlus/LibCxx.h

+3
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *,
123123
SyntheticChildrenFrontEnd *LibcxxFunctionFrontEndCreator(CXXSyntheticChildren *,
124124
lldb::ValueObjectSP);
125125

126+
SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
127+
lldb::ValueObjectSP);
128+
126129
SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
127130
lldb::ValueObjectSP);
128131

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===-- LibCxxQueue.cpp -----------------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "LibCxx.h"
11+
#include "lldb/DataFormatters/FormattersHelpers.h"
12+
13+
using namespace lldb;
14+
using namespace lldb_private;
15+
16+
namespace {
17+
18+
class QueueFrontEnd : public SyntheticChildrenFrontEnd {
19+
public:
20+
QueueFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
21+
Update();
22+
}
23+
24+
size_t GetIndexOfChildWithName(const ConstString &name) override {
25+
return m_container_sp ? m_container_sp->GetIndexOfChildWithName(name)
26+
: UINT32_MAX;
27+
}
28+
29+
bool MightHaveChildren() override { return true; }
30+
bool Update() override;
31+
32+
size_t CalculateNumChildren() override {
33+
return m_container_sp ? m_container_sp->GetNumChildren() : 0;
34+
}
35+
36+
ValueObjectSP GetChildAtIndex(size_t idx) override {
37+
return m_container_sp ? m_container_sp->GetChildAtIndex(idx, true)
38+
: nullptr;
39+
}
40+
41+
private:
42+
ValueObjectSP m_container_sp;
43+
};
44+
} // namespace
45+
46+
bool QueueFrontEnd::Update() {
47+
m_container_sp.reset();
48+
ValueObjectSP c_sp = m_backend.GetChildMemberWithName(ConstString("c"), true);
49+
if (!c_sp)
50+
return false;
51+
m_container_sp = c_sp->GetSyntheticValue();
52+
return false;
53+
}
54+
55+
SyntheticChildrenFrontEnd *
56+
formatters::LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
57+
lldb::ValueObjectSP valobj_sp) {
58+
if (valobj_sp)
59+
return new QueueFrontEnd(*valobj_sp);
60+
return nullptr;
61+
}

0 commit comments

Comments
 (0)