@@ -39,6 +39,51 @@ using namespace lldb_private;
3939using namespace llvm ::dwarf;
4040
4141namespace {
42+ // / A mock implementation of DWARFExpression::Delegate for testing.
43+ // / This class provides default implementations of all delegate methods,
44+ // / with the DWARF version being configurable via the constructor.
45+ class MockDwarfDelegate : public DWARFExpression ::Delegate {
46+ public:
47+ static constexpr uint16_t DEFAULT_DWARF_VERSION = 5 ;
48+ static MockDwarfDelegate Dwarf5 () { return MockDwarfDelegate (5 ); }
49+ static MockDwarfDelegate Dwarf2 () { return MockDwarfDelegate (2 ); }
50+
51+ MockDwarfDelegate () : MockDwarfDelegate(DEFAULT_DWARF_VERSION) {}
52+ explicit MockDwarfDelegate (uint16_t version) : m_version(version) {}
53+
54+ uint16_t GetVersion () const override { return m_version; }
55+
56+ dw_addr_t GetBaseAddress () const override { return 0 ; }
57+
58+ uint8_t GetAddressByteSize () const override { return 4 ; }
59+
60+ llvm::Expected<std::pair<uint64_t , bool >>
61+ GetDIEBitSizeAndSign (uint64_t relative_die_offset) const override {
62+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
63+ " GetDIEBitSizeAndSign not implemented" );
64+ }
65+
66+ dw_addr_t ReadAddressFromDebugAddrSection (uint32_t index) const override {
67+ return 0 ;
68+ }
69+
70+ lldb::offset_t GetVendorDWARFOpcodeSize (const DataExtractor &data,
71+ const lldb::offset_t data_offset,
72+ const uint8_t op) const override {
73+ return LLDB_INVALID_OFFSET;
74+ }
75+
76+ bool ParseVendorDWARFOpcode (uint8_t op, const DataExtractor &opcodes,
77+ lldb::offset_t &offset, RegisterContext *reg_ctx,
78+ lldb::RegisterKind reg_kind,
79+ DWARFExpression::Stack &stack) const override {
80+ return false ;
81+ }
82+
83+ private:
84+ uint16_t m_version;
85+ };
86+
4287struct MockProcess : Process {
4388 MockProcess (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
4489 : Process(target_sp, listener_sp) {}
@@ -164,7 +209,7 @@ class MockRegisterContext : public RegisterContext {
164209
165210static llvm::Expected<Value> Evaluate (llvm::ArrayRef<uint8_t > expr,
166211 lldb::ModuleSP module_sp = {},
167- DWARFUnit *unit = nullptr ,
212+ DWARFExpression::Delegate *unit = nullptr ,
168213 ExecutionContext *exe_ctx = nullptr ,
169214 RegisterContext *reg_ctx = nullptr ) {
170215 DataExtractor extractor (expr.data (), expr.size (), lldb::eByteOrderLittle,
@@ -505,6 +550,19 @@ TEST(DWARFExpression, DW_OP_stack_value) {
505550 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_stack_value}), llvm::Failed ());
506551}
507552
553+ TEST (DWARFExpression, dwarf_version) {
554+ MockDwarfDelegate dwarf2 = MockDwarfDelegate::Dwarf2 ();
555+ MockDwarfDelegate dwarf5 = MockDwarfDelegate::Dwarf5 ();
556+
557+ // In dwarf2 the constant on top of the stack is treated as a value.
558+ EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_lit1}, {}, &dwarf2), ExpectScalar (1 ));
559+
560+ // In dwarf5 the constant on top of the stack is implicitly converted to an
561+ // address.
562+ EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_lit1}, {}, &dwarf5),
563+ ExpectLoadAddress (1 ));
564+ }
565+
508566TEST (DWARFExpression, DW_OP_piece) {
509567 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const2u, 0x11 , 0x22 , DW_OP_piece, 2 ,
510568 DW_OP_const2u, 0x33 , 0x44 , DW_OP_piece, 2 }),
0 commit comments