[Lldb-commits] [lldb] 6a85b9d - Support expressions in the context of a reference
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Tue Jun 21 05:41:51 PDT 2022
Author: Emre Kultursay
Date: 2022-06-21T14:30:07+02:00
New Revision: 6a85b9d16387ddd7c356336c8a77ba6b88f9a610
URL: https://github.com/llvm/llvm-project/commit/6a85b9d16387ddd7c356336c8a77ba6b88f9a610
DIFF: https://github.com/llvm/llvm-project/commit/6a85b9d16387ddd7c356336c8a77ba6b88f9a610.diff
LOG: Support expressions in the context of a reference
...type variable by dereferencing the variable before
evaluating the expression.
Reviewed By: labath
Differential Revision: https://reviews.llvm.org/D128126
Added:
Modified:
lldb/source/Expression/UserExpression.cpp
lldb/test/API/commands/expression/context-object/TestContextObject.py
lldb/test/API/commands/expression/context-object/main.cpp
Removed:
################################################################################
diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp
index fd26cbd0a6ccc..f821603f03e56 100644
--- a/lldb/source/Expression/UserExpression.cpp
+++ b/lldb/source/Expression/UserExpression.cpp
@@ -145,8 +145,9 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
Log *log(GetLog(LLDBLog::Expressions | LLDBLog::Step));
if (ctx_obj) {
- static unsigned const ctx_type_mask =
- lldb::TypeFlags::eTypeIsClass | lldb::TypeFlags::eTypeIsStructUnion;
+ static unsigned const ctx_type_mask = lldb::TypeFlags::eTypeIsClass |
+ lldb::TypeFlags::eTypeIsStructUnion |
+ lldb::TypeFlags::eTypeIsReference;
if (!(ctx_obj->GetTypeInfo() & ctx_type_mask)) {
LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of "
"an invalid type, can't run expressions.");
@@ -155,6 +156,21 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
}
}
+ if (ctx_obj && ctx_obj->GetTypeInfo() & lldb::TypeFlags::eTypeIsReference) {
+ Status error;
+ lldb::ValueObjectSP deref_ctx_sp = ctx_obj->Dereference(error);
+ if (!error.Success()) {
+ LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of "
+ "a reference type that can't be dereferenced, can't run "
+ "expressions.");
+ error.SetErrorString(
+ "passed context object of an reference type cannot be deferenced");
+ return lldb::eExpressionSetupError;
+ }
+
+ ctx_obj = deref_ctx_sp.get();
+ }
+
lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
lldb::LanguageType language = options.GetLanguage();
const ResultType desired_type = options.DoesCoerceToId()
diff --git a/lldb/test/API/commands/expression/context-object/TestContextObject.py b/lldb/test/API/commands/expression/context-object/TestContextObject.py
index a53cbac306503..45f7a003837b9 100644
--- a/lldb/test/API/commands/expression/context-object/TestContextObject.py
+++ b/lldb/test/API/commands/expression/context-object/TestContextObject.py
@@ -16,34 +16,34 @@ def test_context_object(self):
frame = thread.GetFrameAtIndex(0)
#
- # Test C++ struct variable
+ # Test C++ struct variable and reference-to-struct variable
#
-
- obj_val = frame.FindVariable("cpp_struct")
- self.assertTrue(obj_val.IsValid())
-
- # Test an empty expression evaluation
- value = obj_val.EvaluateExpression("")
- self.assertFalse(value.IsValid())
- self.assertFalse(value.GetError().Success())
-
- # Test retrieveing of a field (not a local with the same name)
- value = obj_val.EvaluateExpression("field")
- self.assertTrue(value.IsValid())
- self.assertSuccess(value.GetError())
- self.assertEqual(value.GetValueAsSigned(), 1111)
-
- # Test functions evaluation
- value = obj_val.EvaluateExpression("function()")
- self.assertTrue(value.IsValid())
- self.assertSuccess(value.GetError())
- self.assertEqual(value.GetValueAsSigned(), 2222)
-
- # Test that we retrieve the right global
- value = obj_val.EvaluateExpression("global.field")
- self.assertTrue(value.IsValid())
- self.assertSuccess(value.GetError())
- self.assertEqual(value.GetValueAsSigned(), 1111)
+ for obj in "cpp_struct", "cpp_struct_ref":
+ obj_val = frame.FindVariable(obj)
+ self.assertTrue(obj_val.IsValid())
+
+ # Test an empty expression evaluation
+ value = obj_val.EvaluateExpression("")
+ self.assertFalse(value.IsValid())
+ self.assertFalse(value.GetError().Success())
+
+ # Test retrieveing of a field (not a local with the same name)
+ value = obj_val.EvaluateExpression("field")
+ self.assertTrue(value.IsValid())
+ self.assertSuccess(value.GetError())
+ self.assertEqual(value.GetValueAsSigned(), 1111)
+
+ # Test functions evaluation
+ value = obj_val.EvaluateExpression("function()")
+ self.assertTrue(value.IsValid())
+ self.assertSuccess(value.GetError())
+ self.assertEqual(value.GetValueAsSigned(), 2222)
+
+ # Test that we retrieve the right global
+ value = obj_val.EvaluateExpression("global.field")
+ self.assertTrue(value.IsValid())
+ self.assertSuccess(value.GetError())
+ self.assertEqual(value.GetValueAsSigned(), 1111)
#
# Test C++ union variable
diff --git a/lldb/test/API/commands/expression/context-object/main.cpp b/lldb/test/API/commands/expression/context-object/main.cpp
index 098b6089fce01..4306e9520c010 100644
--- a/lldb/test/API/commands/expression/context-object/main.cpp
+++ b/lldb/test/API/commands/expression/context-object/main.cpp
@@ -31,6 +31,9 @@ int main()
cpp_namespace::CppStruct cpp_struct = cpp_namespace::GetCppStruct();
cpp_struct.function();
+ cpp_namespace::CppStruct &cpp_struct_ref = cpp_struct;
+ cpp_struct_ref.function();
+
int field = 4444;
cpp_namespace::CppUnion cpp_union;
More information about the lldb-commits
mailing list