[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