Skip to content

Commit 2149db1

Browse files
committed
Implement LLDBParser::enumerateClassMembers
1 parent fb95686 commit 2149db1

File tree

4 files changed

+65
-20
lines changed

4 files changed

+65
-20
lines changed

oi/type_graph/LLDBParser.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <glog/logging.h>
1919
#include <lldb/API/LLDB.h>
20+
#include <cassert>
2021

2122
namespace oi::detail::type_graph {
2223

@@ -97,7 +98,7 @@ Type& LLDBParser::enumerateType(lldb::SBType& type) {
9798

9899
Class& LLDBParser::enumerateClass(lldb::SBType& type) {
99100
auto name = type.GetName();
100-
auto displayName = type.GetDisplayTypeName();
101+
auto displayName = type.GetUnqualifiedType().GetDisplayTypeName();
101102
auto size = type.GetByteSize();
102103
auto virtuality = type.IsPolymorphicClass();
103104

@@ -117,9 +118,34 @@ Class& LLDBParser::enumerateClass(lldb::SBType& type) {
117118
}
118119

119120
auto &c = makeType<Class>(type, kind, displayName, name, size, virtuality);
121+
122+
enumerateClassMembers(type, c.members);
123+
120124
return c;
121125
}
122126

127+
void LLDBParser::enumerateClassMembers(lldb::SBType& type, std::vector<Member>& members) {
128+
assert(members.empty());
129+
members.reserve(type.GetNumberOfFields());
130+
131+
for (uint32_t i = 0; i < type.GetNumberOfFields(); i++) {
132+
auto field = type.GetFieldAtIndex(i);
133+
if (field.GetName() == nullptr)
134+
continue; // Skip anonymous fields (TODO: Why?)
135+
auto fieldName = field.GetName();
136+
auto fieldType = field.GetType();
137+
auto bitFieldSize = field.GetBitfieldSizeInBits();
138+
auto bitOffset = field.GetOffsetInBits();
139+
140+
auto& enumeratedField = enumerateType(fieldType);
141+
members.emplace_back(enumeratedField, fieldName, bitOffset, bitFieldSize);
142+
}
143+
144+
std::sort(members.begin(), members.end(), [](const auto& a, const auto& b) {
145+
return a.bitOffset < b.bitOffset;
146+
});
147+
}
148+
123149
Enum& LLDBParser::enumerateEnum(lldb::SBType& type) {
124150
const char *typeName = type.GetName();
125151
std::string name = typeName ? typeName : "";

oi/type_graph/LLDBParser.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ class LLDBParser {
6767
Primitive::Kind primitiveIntKind(lldb::SBType& type, bool is_signed);
6868
Primitive::Kind primitiveFloatKind(lldb::SBType& type);
6969

70+
void enumerateClassMembers(lldb::SBType& type, std::vector<Member>& members);
71+
7072
bool chasePointer() const;
7173

72-
template <typename T, typename... Args>
74+
template <typename T, typename... Args>
7375
T& makeType(lldb::SBType& lldbType, Args&&... args) {
7476
auto& newType = typeGraph_.makeType<T>(std::forward<Args>(args)...);
7577
lldb_types_.emplace(lldbType, newType);

test/integration/alignment.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,21 @@ definitions = '''
4141
};
4242
'''
4343
[cases]
44+
[cases.struct]
45+
param_types = ["const Align16&"]
46+
setup = "return {};"
47+
expect_json = '''[
48+
{"staticSize": 16, "exclusiveSize": 15, "members": [
49+
{"typeName": "int8_t", "staticSize": 1, "exclusiveSize": 1}
50+
]}]'''
51+
[cases.member_alignment]
52+
param_types = ["const MemberAlignment&"]
53+
setup = "return {};"
54+
expect_json = '''[
55+
{"staticSize": 64, "exclusiveSize": 32, "members": [
56+
{"typeName": "int8_t", "staticSize": 1, "exclusiveSize": 1},
57+
{"typeName": "int8_t", "staticSize": 1, "exclusiveSize": 1}
58+
]}]'''
4459
[cases.wrapper_struct]
4560
param_types = ["const Wrapper<Align16>&"]
4661
setup = "return {};"

test/test_lldb_parser.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void LLDBParserTest::test(std::string_view function,
8383
std::string_view expected) {
8484
// Enable options in unit tests so we get more coverage
8585
LLDBParserOptions options = {
86+
.chaseRawPointers = true,
8687
.readEnumValues = true,
8788
};
8889
test(function, expected, options);
@@ -129,7 +130,7 @@ void LLDBParserTest::testMultiCompilerGlob(
129130
TEST_F(LLDBParserTest, SimpleStruct) {
130131
test("oid_test_case_simple_struct", R"(
131132
[1] Pointer
132-
[0] Struct: SimpleStruct (size: 16)
133+
[0] Struct: ns_simple::SimpleStruct (size: 16)
133134
Member: a (offset: 0)
134135
Primitive: int32_t
135136
Member: b (offset: 4)
@@ -142,7 +143,7 @@ TEST_F(LLDBParserTest, SimpleStruct) {
142143
TEST_F(LLDBParserTest, SimpleClass) {
143144
test("oid_test_case_simple_class", R"(
144145
[1] Pointer
145-
[0] Class: SimpleClass (size: 16)
146+
[0] Class: ns_simple::SimpleClass (size: 16)
146147
Member: a (offset: 0)
147148
Primitive: int32_t
148149
Member: b (offset: 4)
@@ -155,7 +156,7 @@ TEST_F(LLDBParserTest, SimpleClass) {
155156
TEST_F(LLDBParserTest, SimpleUnion) {
156157
test("oid_test_case_simple_union", R"(
157158
[1] Pointer
158-
[0] Union: SimpleUnion (size: 8)
159+
[0] Union: ns_simple::SimpleUnion (size: 8)
159160
Member: a (offset: 0)
160161
Primitive: int32_t
161162
Member: b (offset: 0)
@@ -324,7 +325,7 @@ TEST_F(LLDBParserTest, Using) {
324325
TEST_F(LLDBParserTest, ArrayMember) {
325326
test("oid_test_case_arrays_member_int10", R"(
326327
[2] Pointer
327-
[0] Struct: Foo10 (size: 40)
328+
[0] Struct: ns_arrays::Foo10 (size: 40)
328329
Member: arr (offset: 0)
329330
[1] Array: (length: 10)
330331
Primitive: int32_t
@@ -349,7 +350,7 @@ TEST_F(LLDBParserTest, ArrayDirect) {
349350
TEST_F(LLDBParserTest, Pointer) {
350351
test("oid_test_case_pointers_struct_primitive_ptrs", R"(
351352
[3] Pointer
352-
[0] Struct: PrimitivePtrs (size: 24)
353+
[0] Struct: ns_pointers::PrimitivePtrs (size: 24)
353354
Member: a (offset: 0)
354355
Primitive: int32_t
355356
Member: b (offset: 8)
@@ -366,7 +367,7 @@ TEST_F(LLDBParserTest, PointerNoFollow) {
366367
test("oid_test_case_pointers_struct_primitive_ptrs",
367368
R"(
368369
[1] Pointer
369-
[0] Struct: PrimitivePtrs (size: 24)
370+
[0] Struct: ns_pointers::PrimitivePtrs (size: 24)
370371
Member: a (offset: 0)
371372
Primitive: int32_t
372373
Member: b (offset: 8)
@@ -516,18 +517,20 @@ TEST_F(LLDBParserTest, TemplateEnumValueNegative) {
516517
//}
517518

518519
TEST_F(LLDBParserTest, StructAlignment) {
520+
GTEST_SKIP() << "Alignment not reported by LLDB yet";
519521
test("oid_test_case_alignment_struct", R"(
520522
[1] Pointer
521-
[0] Struct: Align16 (size: 16, align: 16)
523+
[0] Struct: ns_alignment::Align16 (size: 16, align: 16)
522524
Member: c (offset: 0)
523525
Primitive: int8_t
524526
)");
525527
}
526528

527529
TEST_F(LLDBParserTest, MemberAlignment) {
530+
GTEST_SKIP() << "Alignment not reported by LLDB yet";
528531
test("oid_test_case_alignment_member_alignment", R"(
529532
[1] Pointer
530-
[0] Struct: MemberAlignment (size: 64)
533+
[0] Struct: ns_alignment::MemberAlignment (size: 64)
531534
Member: c (offset: 0)
532535
Primitive: int8_t
533536
Member: c32 (offset: 32, align: 32)
@@ -567,7 +570,7 @@ TEST_F(LLDBParserTest, VirtualFunctions) {
567570
TEST_F(LLDBParserTest, BitfieldsSingle) {
568571
test("oid_test_case_bitfields_single", R"(
569572
[1] Pointer
570-
[0] Struct: Single (size: 4)
573+
[0] Struct: ns_bitfields::Single (size: 4)
571574
Member: bitfield (offset: 0, bitsize: 3)
572575
Primitive: int32_t
573576
)");
@@ -576,7 +579,7 @@ TEST_F(LLDBParserTest, BitfieldsSingle) {
576579
TEST_F(LLDBParserTest, BitfieldsWithinBytes) {
577580
test("oid_test_case_bitfields_within_bytes", R"(
578581
[1] Pointer
579-
[0] Struct: WithinBytes (size: 2)
582+
[0] Struct: ns_bitfields::WithinBytes (size: 2)
580583
Member: a (offset: 0, bitsize: 3)
581584
Primitive: int8_t
582585
Member: b (offset: 0.375, bitsize: 5)
@@ -589,7 +592,7 @@ TEST_F(LLDBParserTest, BitfieldsWithinBytes) {
589592
TEST_F(LLDBParserTest, BitfieldsStraddleBytes) {
590593
test("oid_test_case_bitfields_straddle_bytes", R"(
591594
[1] Pointer
592-
[0] Struct: StraddleBytes (size: 3)
595+
[0] Struct: ns_bitfields::StraddleBytes (size: 3)
593596
Member: a (offset: 0, bitsize: 7)
594597
Primitive: int8_t
595598
Member: b (offset: 1, bitsize: 7)
@@ -602,7 +605,7 @@ TEST_F(LLDBParserTest, BitfieldsStraddleBytes) {
602605
TEST_F(LLDBParserTest, BitfieldsMixed) {
603606
test("oid_test_case_bitfields_mixed", R"(
604607
[1] Pointer
605-
[0] Struct: Mixed (size: 12)
608+
[0] Struct: ns_bitfields::Mixed (size: 12)
606609
Member: a (offset: 0)
607610
Primitive: int32_t
608611
Member: b (offset: 4, bitsize: 4)
@@ -617,10 +620,9 @@ TEST_F(LLDBParserTest, BitfieldsMixed) {
617620
}
618621

619622
TEST_F(LLDBParserTest, BitfieldsMoreBitsThanType) {
620-
GTEST_SKIP() << "LLDB errors out";
621623
test("oid_test_case_bitfields_more_bits_than_type", R"(
622624
[1] Pointer
623-
[0] Struct: MoreBitsThanType (size: 4)
625+
[0] Struct: ns_bitfields::MoreBitsThanType (size: 4)
624626
Member: a (offset: 0, bitsize: 8)
625627
Primitive: int8_t
626628
)");
@@ -629,7 +631,7 @@ TEST_F(LLDBParserTest, BitfieldsMoreBitsThanType) {
629631
TEST_F(LLDBParserTest, BitfieldsZeroBits) {
630632
test("oid_test_case_bitfields_zero_bits", R"(
631633
[1] Pointer
632-
[0] Struct: ZeroBits (size: 2)
634+
[0] Struct: ns_bitfields::ZeroBits (size: 2)
633635
Member: b1 (offset: 0, bitsize: 3)
634636
Primitive: int8_t
635637
Member: b2 (offset: 1, bitsize: 2)
@@ -640,14 +642,14 @@ TEST_F(LLDBParserTest, BitfieldsZeroBits) {
640642
TEST_F(LLDBParserTest, BitfieldsEnum) {
641643
test("oid_test_case_bitfields_enum", R"(
642644
[1] Pointer
643-
[0] Struct: Enum (size: 4)
645+
[0] Struct: ns_bitfields::Enum (size: 4)
644646
Member: e (offset: 0, bitsize: 2)
645-
Enum: MyEnum (size: 4)
647+
Enum: ns_bitfields::MyEnum (size: 4)
646648
Enumerator: 0:One
647649
Enumerator: 1:Two
648650
Enumerator: 2:Three
649651
Member: f (offset: 0.25, bitsize: 4)
650-
Enum: MyEnum (size: 4)
652+
Enum: ns_bitfields::MyEnum (size: 4)
651653
Enumerator: 0:One
652654
Enumerator: 1:Two
653655
Enumerator: 2:Three

0 commit comments

Comments
 (0)