Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,18 @@ std::optional<int64_t> GetIndexValue(ValueObject &valobj) {
ValueObjectSP GetNthStorage(ValueObject &outer, int64_t index) {
// We need to find the std::_Variant_storage base class.

// -> std::_SMF_control (typedef to std::_Variant_base)
ValueObjectSP container_sp = outer.GetSP()->GetChildAtIndex(0);
if (!container_sp)
// Navigate "down" to std::_Variant_base by finding the holder of "_Which".
// This might be down a few levels if a variant member isn't trivially
// destructible/copyable/etc.
ValueObjectSP which_sp = outer.GetChildMemberWithName("_Which");
Comment on lines +70 to +73
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this related to making it run with PDB? Or is this about handling more kinds of variant layouts in general? Is that where the additional test-case comes from? If it's the latter I'd prefer it if we split it into a separate PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh the title of this PR answers my question. Yea probably better to do the two changes separately

if (!which_sp)
return nullptr;
ValueObject *parent = which_sp->GetParent();
if (!parent)
return nullptr;
// -> std::_Variant_storage
container_sp = container_sp->GetChildAtIndex(0);

// Now go to std::_Variant_storage.
ValueObjectSP container_sp = parent->GetChildAtIndex(0);
if (!container_sp)
return nullptr;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ def cleanup():
],
)

self.expect_expr(
"v4",
result_summary=" Active Type = int ",
result_children=[
ValueCheck(name="Value", value="4"),
],
)

lldbutil.continue_to_breakpoint(self.process, bkpt)

self.expect(
Expand All @@ -69,6 +77,19 @@ def cleanup():
substrs=["v3 = Active Type = char {", "Value = 'A'", "}"],
)

string_name = (
"std::basic_string<char, std::char_traits<char>, std::allocator<char>>"
if self.getDebugInfo() == "pdb"
else "std::basic_string<char>"
)
self.expect_expr(
"v4",
result_summary=f" Active Type = {string_name} ",
result_children=[
ValueCheck(name="Value", summary='"a string"'),
],
)

self.expect("frame variable v_valueless", substrs=["v_valueless = No Value"])

self.expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ int main() {
S>
v_300_types_valueless;

std::variant<int, bool, std::string> v4 = 4;

v_valueless = 5;
v_300_types_valueless.emplace<0>(10);

Expand All @@ -70,6 +72,9 @@ int main() {
// state when we change its value.
v1 = 2.0;
d = std::get<double>(v1);

v4 = "a string";

printf("%f\n", d); // break here

try {
Expand Down
Loading