Skip to content

Commit 92d3029

Browse files
authored
[LLDB] Fix GetIndexOfChildMemberWithName to handle anonymous structs. (#138487)
When handling anonymous structs, GetIndexOfChildMemberWithName needs to add the number of non-empty base classes to the child index, to get the actual correct index. It was not doing so. This fixes that.
1 parent dc28f9d commit 92d3029

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6743,7 +6743,9 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
67436743
if (field_name.empty()) {
67446744
CompilerType field_type = GetType(field->getType());
67456745
std::vector<uint32_t> save_indices = child_indexes;
6746-
child_indexes.push_back(child_idx);
6746+
child_indexes.push_back(
6747+
child_idx + TypeSystemClang::GetNumBaseClasses(
6748+
cxx_record_decl, omit_empty_base_classes));
67476749
if (field_type.GetIndexOfChildMemberWithName(
67486750
name, omit_empty_base_classes, child_indexes))
67496751
return child_indexes.size();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CXX_SOURCES := main.cpp
2+
3+
include Makefile.rules
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""
2+
Test that we properly print multiple types.
3+
"""
4+
5+
import lldb
6+
import lldbsuite.test.lldbutil as lldbutil
7+
from lldbsuite.test.lldbtest import *
8+
from lldbsuite.test import decorators
9+
10+
11+
class TestTypeLookupAnonStruct(TestBase):
12+
def test_lookup_anon_struct(self):
13+
self.build()
14+
lldbutil.run_to_source_breakpoint(
15+
self, "// Set breakpoint here", lldb.SBFileSpec("main.cpp")
16+
)
17+
18+
self.expect_var_path("unnamed_derived.y", value="2")
19+
self.expect_var_path("unnamed_derived.z", value="13")
20+
self.expect(
21+
'frame variable "derb.x"',
22+
error=True,
23+
substrs=['"x" is not a member of "(DerivedB) derb"']
24+
)
25+
self.expect(
26+
'frame variable "derb.y"',
27+
error=True,
28+
substrs=['"y" is not a member of "(DerivedB) derb"']
29+
)
30+
self.expect_var_path("derb.w", value="14")
31+
self.expect_var_path("derb.k", value="15")
32+
self.expect_var_path("derb.a.x", value="1")
33+
self.expect_var_path("derb.a.y", value="2")
34+
35+
self.expect_var_path("multi1.m", value="16")
36+
self.expect_var_path("multi1.y", value="30")
37+
38+
self.expect_var_path("multi2.i", value="42")
39+
self.expect_var_path("multi2.w", value="23")
40+
self.expect_var_path("multi2.a.x", value="1")
41+
self.expect_var_path("multi2.a.y", value="2")
42+
self.expect_var_path("multi2.y", value="2")
43+
self.expect_var_path("multi2.n", value="7")
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
int main(int argc, char **argv) {
2+
struct A {
3+
struct {
4+
int x = 1;
5+
};
6+
int y = 2;
7+
} a;
8+
9+
struct B {
10+
// Anonymous struct inherits another struct.
11+
struct : public A {
12+
int z = 3;
13+
};
14+
int w = 4;
15+
A a;
16+
} b;
17+
18+
19+
struct EmptyBase {
20+
};
21+
22+
struct : public A {
23+
struct {
24+
int z = 13;
25+
};
26+
} unnamed_derived;
27+
28+
struct DerivedB : public B {
29+
struct {
30+
// `w` in anonymous struct shadows `w` from `B`.
31+
int w = 14;
32+
int k = 15;
33+
};
34+
} derb;
35+
36+
struct MultiBase : public EmptyBase, public A {
37+
struct {
38+
int m = 16;
39+
int y = 30;
40+
};
41+
} multi1;
42+
43+
struct MB2 : public B, EmptyBase, public A {
44+
int i = 42;
45+
struct {
46+
int w = 23;
47+
int n = 7;
48+
};
49+
} multi2;
50+
51+
return 0; // Set breakpoint here
52+
}

0 commit comments

Comments
 (0)