From 565bdb55453f0bdd59d9325b8a748cb42e6df95b Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 25 Apr 2024 09:06:48 +0200 Subject: [lldb] Add SB API to access static constexpr member values (#89730) The main change is the addition of a new SBTypeStaticField class, representing a static member of a class. It can be retrieved created through SBType::GetStaticFieldWithName. It contains several methods (GetName, GetMangledName, etc.) whose meaning is hopefully obvious. The most interesting method is lldb::SBValue GetConstantValue(lldb::SBTarget) which returns a the value of the field -- if it is a compile time constant. The reason for that is that only constants have their values represented in the clang AST. For non-constants, we need to go back to the module containing that constant, and ask retrieve the associated ValueObjectVariable. That's easy enough if the we are still in the type system of the module (because then the type system will contain the pointer to the module symbol file), but it's hard when the type has been copied into another AST (e.g. during expression evaluation). To do that we would need to walk the ast import chain backwards to find the source TypeSystem, and I haven't found a nice way to do that. Another possibility would be to use the mangled name of the variable to perform a lookup (in all modules). That is sort of what happens when evaluating the variable in an expression (which does work), but I did not want to commit to that implementation as it's not necessary for my use case (and if anyone wants to, he can use the GetMangledName function and perform the lookup manually). The patch adds a couple of new TypeSystem functions to surface the information needed to implement this functionality. --- lldb/test/API/python_api/type/TestTypeList.py | 33 +++++++++++++++++++++++++++ lldb/test/API/python_api/type/main.cpp | 3 +++ 2 files changed, 36 insertions(+) (limited to 'lldb/test/API/python_api') diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py index c647c2b..81c44f7 100644 --- a/lldb/test/API/python_api/type/TestTypeList.py +++ b/lldb/test/API/python_api/type/TestTypeList.py @@ -33,6 +33,32 @@ class TypeAndTypeListTestCase(TestBase): self.assertTrue(pointer_masks2_type) self.DebugSBType(pointer_masks2_type) + def _find_static_field_in_Task_pointer(self, task_pointer): + self.assertTrue(task_pointer) + self.DebugSBType(task_pointer) + + task_type = task_pointer.GetPointeeType() + self.assertTrue(task_type) + self.DebugSBType(task_type) + + static_constexpr_field = task_type.GetStaticFieldWithName( + "static_constexpr_field" + ) + self.assertTrue(static_constexpr_field) + self.assertEqual(static_constexpr_field.GetName(), "static_constexpr_field") + self.assertEqual(static_constexpr_field.GetType().GetName(), "const long") + + value = static_constexpr_field.GetConstantValue(self.target()) + self.DebugSBValue(value) + self.assertEqual(value.GetValueAsSigned(), 47) + + static_mutable_field = task_type.GetStaticFieldWithName("static_mutable_field") + self.assertTrue(static_mutable_field) + self.assertEqual(static_mutable_field.GetName(), "static_mutable_field") + self.assertEqual(static_mutable_field.GetType().GetName(), "int") + + self.assertFalse(static_mutable_field.GetConstantValue(self.target())) + @skipIf(compiler="clang", compiler_version=["<", "17.0"]) def test(self): """Exercise SBType and SBTypeList API.""" @@ -175,6 +201,13 @@ class TypeAndTypeListTestCase(TestBase): frame0.EvaluateExpression("pointer").GetType() ) + self._find_static_field_in_Task_pointer( + frame0.FindVariable("task_head").GetType() + ) + self._find_static_field_in_Task_pointer( + frame0.EvaluateExpression("task_head").GetType() + ) + # We'll now get the child member 'id' from 'task_head'. id = task_head.GetChildMemberWithName("id") self.DebugSBValue(id) diff --git a/lldb/test/API/python_api/type/main.cpp b/lldb/test/API/python_api/type/main.cpp index 391f58e..c86644d 100644 --- a/lldb/test/API/python_api/type/main.cpp +++ b/lldb/test/API/python_api/type/main.cpp @@ -27,12 +27,15 @@ public: enum E : unsigned char {} e; union U { } u; + static constexpr long static_constexpr_field = 47; + static int static_mutable_field; Task(int i, Task *n): id(i), next(n), type(TASK_TYPE_1) {} }; +int Task::static_mutable_field = 42; template struct PointerInfo { enum Masks1 { pointer_mask }; -- cgit v1.1