diff --git a/lldb/include/lldb/ValueObject/ValueObjectSynthetic.h b/lldb/include/lldb/ValueObject/ValueObjectSynthetic.h index 063d796ee4eec..1a82fd78bbba3 100644 --- a/lldb/include/lldb/ValueObject/ValueObjectSynthetic.h +++ b/lldb/include/lldb/ValueObject/ValueObjectSynthetic.h @@ -123,6 +123,11 @@ class ValueObjectSynthetic : public ValueObject { void SetLanguageFlags(uint64_t flags) override; + void + GetExpressionPath(Stream &stream, + GetExpressionPathFormat epformat = + eGetExpressionPathFormatDereferencePointers) override; + protected: bool UpdateValue() override; diff --git a/lldb/source/ValueObject/ValueObjectSynthetic.cpp b/lldb/source/ValueObject/ValueObjectSynthetic.cpp index f673c51a88412..1b689257224df 100644 --- a/lldb/source/ValueObject/ValueObjectSynthetic.cpp +++ b/lldb/source/ValueObject/ValueObjectSynthetic.cpp @@ -443,3 +443,15 @@ void ValueObjectSynthetic::SetLanguageFlags(uint64_t flags) { else this->ValueObject::SetLanguageFlags(flags); } + +void ValueObjectSynthetic::GetExpressionPath(Stream &stream, + GetExpressionPathFormat epformat) { + if (const lldb::ValueType obj_value_type = GetValueType(); + IsSynthetic() && (obj_value_type == lldb::eValueTypeRegister || + obj_value_type == lldb::eValueTypeRegisterSet)) { + + if (const lldb::ValueObjectSP raw_value = GetNonSyntheticValue()) + return raw_value->GetExpressionPath(stream, epformat); + } + return ValueObject::GetExpressionPath(stream, epformat); +} diff --git a/lldb/test/API/python_api/exprpath_register/Makefile b/lldb/test/API/python_api/exprpath_register/Makefile new file mode 100644 index 0000000000000..10495940055b6 --- /dev/null +++ b/lldb/test/API/python_api/exprpath_register/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/python_api/exprpath_register/TestExprPathRegisters.py b/lldb/test/API/python_api/exprpath_register/TestExprPathRegisters.py new file mode 100644 index 0000000000000..4ffbc5e49fb0d --- /dev/null +++ b/lldb/test/API/python_api/exprpath_register/TestExprPathRegisters.py @@ -0,0 +1,64 @@ +""" +Test Getting the expression path for registers works correctly +""" + +import lldb +from lldbsuite.test import lldbutil +from lldbsuite.test.lldbtest import TestBase, VALID_BREAKPOINT, VALID_TARGET + + +class TestExprPathRegisters(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + def verify_register_path(self, reg_value: lldb.SBValue): + stream = lldb.SBStream() + reg_name = reg_value.name + self.assertTrue( + reg_value.GetExpressionPath(stream), + f"Expected an expression path for register {reg_name}.", + ) + reg_expr_path = stream.GetData() + self.assertEqual(reg_expr_path, f"${reg_name}") + + def test_float_registers(self): + """Verify the expression path of the registers is valid.""" + self.build() + _, _, thread, _ = lldbutil.run_to_name_breakpoint(self, "my_foo") + frame = thread.GetSelectedFrame() + self.assertTrue(frame, "Expected a valid Frame.") + + # possible floating point register on some cpus. + register_names = [ + "xmm0", + "ymm0", + "v0", + "v1", + "f0", + "f1", + "d0", + "d1", + "vr0", + "vr1", + "st0", + "st1", + ] + for name in register_names: + reg_value = frame.FindRegister(name) + # some the register will not be available for the cpu + # only verify if it is valid. + if reg_value: + self.verify_register_path(reg_value) + + def test_all_registers(self): + """Test all the registers that is avaiable on the machine""" + self.build() + _, _, thread, _ = lldbutil.run_to_name_breakpoint(self, "my_foo") + frame = thread.GetSelectedFrame() + self.assertTrue(frame, "Expected a valid Frame.") + + register_sets = frame.GetRegisters() + self.assertTrue(register_sets.IsValid(), "Expected Frame Registers") + + for register_set in register_sets: + for register in register_set.children: + self.verify_register_path(register) diff --git a/lldb/test/API/python_api/exprpath_register/main.c b/lldb/test/API/python_api/exprpath_register/main.c new file mode 100644 index 0000000000000..4809a87cdf210 --- /dev/null +++ b/lldb/test/API/python_api/exprpath_register/main.c @@ -0,0 +1,10 @@ + +float my_foo() { + float result = 10.0 + 20.0; + return result; +} + +int main(void) { + float result = my_foo(); + return (int)result; +}