Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add data formatter for libstdc++ tuple
Differential revision: https://reviews.llvm.org/D25733 llvm-svn: 284829
- Loading branch information
Tamas Berghammer
committed
Oct 21, 2016
1 parent
0789722
commit 7f15dba
Showing
7 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
...lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/tuple/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
LEVEL = ../../../../../make | ||
|
||
CXX_SOURCES := main.cpp | ||
|
||
USE_LIBSTDCPP := 1 | ||
CFLAGS_EXTRAS += $(NO_LIMIT_DEBUG_INFO_FLAGS) | ||
|
||
include $(LEVEL)/Makefile.rules |
49 changes: 49 additions & 0 deletions
49
...ionalities/data-formatter/data-formatter-stl/libstdcpp/tuple/TestDataFormatterStdTuple.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
""" | ||
Test lldb data formatter subsystem. | ||
""" | ||
|
||
from __future__ import print_function | ||
|
||
import os | ||
import time | ||
import lldb | ||
from lldbsuite.test.decorators import * | ||
from lldbsuite.test.lldbtest import * | ||
from lldbsuite.test import lldbutil | ||
|
||
|
||
class StdTupleDataFormatterTestCase(TestBase): | ||
mydir = TestBase.compute_mydir(__file__) | ||
|
||
@skipIfFreeBSD | ||
@skipIfWindows # libstdcpp not ported to Windows | ||
@skipIfDarwin # doesn't compile on Darwin | ||
def test_with_run_command(self): | ||
self.build() | ||
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) | ||
|
||
lldbutil.run_break_set_by_source_regexp( | ||
self, "Set break point at this line.") | ||
self.runCmd("run", RUN_SUCCEEDED) | ||
|
||
# The stop reason of the thread should be breakpoint. | ||
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, | ||
substrs=['stopped', 'stop reason = breakpoint']) | ||
|
||
frame = self.frame() | ||
self.assertTrue(frame.IsValid()) | ||
|
||
self.expect("frame variable ti", substrs=['[0] = 1']) | ||
self.expect("frame variable ts", substrs=['[0] = "foobar"']) | ||
self.expect("frame variable tt", substrs=['[0] = 1', '[1] = "baz"', '[2] = 2']) | ||
|
||
self.assertEqual(1, frame.GetValueForVariablePath("ti[0]").GetValueAsUnsigned()) | ||
self.assertFalse(frame.GetValueForVariablePath("ti[1]").IsValid()) | ||
|
||
self.assertEqual('"foobar"', frame.GetValueForVariablePath("ts[0]").GetSummary()) | ||
self.assertFalse(frame.GetValueForVariablePath("ts[1]").IsValid()) | ||
|
||
self.assertEqual(1, frame.GetValueForVariablePath("tt[0]").GetValueAsUnsigned()) | ||
self.assertEqual('"baz"', frame.GetValueForVariablePath("tt[1]").GetSummary()) | ||
self.assertEqual(2, frame.GetValueForVariablePath("tt[2]").GetValueAsUnsigned()) | ||
self.assertFalse(frame.GetValueForVariablePath("tt[3]").IsValid()) |
9 changes: 9 additions & 0 deletions
9
...lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/tuple/main.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#include <memory> | ||
#include <string> | ||
|
||
int main() { | ||
std::tuple<int> ti{1}; | ||
std::tuple<std::string> ts{"foobar"}; | ||
std::tuple<int, std::string, int> tt{1, "baz", 2}; | ||
return 0; // Set break point at this line. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
//===-- LibStdcppTuple.cpp --------------------------------------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "LibStdcpp.h" | ||
|
||
#include <memory> | ||
#include <vector> | ||
|
||
#include "lldb/Core/ConstString.h" | ||
#include "lldb/Core/ValueObject.h" | ||
#include "lldb/DataFormatters/FormattersHelpers.h" | ||
#include "lldb/DataFormatters/TypeSynthetic.h" | ||
|
||
using namespace lldb; | ||
using namespace lldb_private; | ||
using namespace lldb_private::formatters; | ||
|
||
namespace { | ||
|
||
class LibStdcppTupleSyntheticFrontEnd : public SyntheticChildrenFrontEnd { | ||
public: | ||
explicit LibStdcppTupleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); | ||
|
||
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: | ||
std::vector<ValueObjectSP> m_members; | ||
}; | ||
|
||
} // end of anonymous namespace | ||
|
||
LibStdcppTupleSyntheticFrontEnd::LibStdcppTupleSyntheticFrontEnd( | ||
lldb::ValueObjectSP valobj_sp) | ||
: SyntheticChildrenFrontEnd(*valobj_sp) { | ||
Update(); | ||
} | ||
|
||
bool LibStdcppTupleSyntheticFrontEnd::Update() { | ||
m_members.clear(); | ||
|
||
ValueObjectSP valobj_backend_sp = m_backend.GetSP(); | ||
if (!valobj_backend_sp) | ||
return false; | ||
|
||
ValueObjectSP next_child_sp = valobj_backend_sp->GetNonSyntheticValue(); | ||
while (next_child_sp != nullptr) { | ||
ValueObjectSP current_child = next_child_sp; | ||
next_child_sp = nullptr; | ||
|
||
size_t child_count = current_child->GetNumChildren(); | ||
for (size_t i = 0; i < child_count; ++i) { | ||
ValueObjectSP child_sp = current_child->GetChildAtIndex(i, true); | ||
llvm::StringRef name_str = child_sp->GetName().GetStringRef(); | ||
if (name_str.startswith("std::_Tuple_impl<")) { | ||
next_child_sp = child_sp; | ||
} else if (name_str.startswith("std::_Head_base<")) { | ||
ValueObjectSP value_sp = | ||
child_sp->GetChildMemberWithName(ConstString("_M_head_impl"), true); | ||
if (value_sp) { | ||
StreamString name; | ||
name.Printf("[%zd]", m_members.size()); | ||
value_sp->SetName(ConstString(name.GetData())); | ||
|
||
m_members.push_back(value_sp); | ||
} | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; } | ||
|
||
lldb::ValueObjectSP | ||
LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(size_t idx) { | ||
if (idx < m_members.size()) | ||
return m_members[idx]; | ||
return lldb::ValueObjectSP(); | ||
} | ||
|
||
size_t LibStdcppTupleSyntheticFrontEnd::CalculateNumChildren() { | ||
return m_members.size(); | ||
} | ||
|
||
size_t LibStdcppTupleSyntheticFrontEnd::GetIndexOfChildWithName( | ||
const ConstString &name) { | ||
return ExtractIndexFromString(name.GetCString()); | ||
} | ||
|
||
SyntheticChildrenFrontEnd * | ||
lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator( | ||
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { | ||
return (valobj_sp ? new LibStdcppTupleSyntheticFrontEnd(valobj_sp) : nullptr); | ||
} |