https://github.com/kuilpd updated 
https://github.com/llvm/llvm-project/pull/222192

>From 858d4947fa11931f15d1fe57686065c4d812da66 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Mon, 7 Sep 2026 21:10:14 +0500
Subject: [PATCH 1/5] [lldb] Use DIL in SBValue::CreateValueFromExpression

---
 lldb/include/lldb/Target/Target.h             |  4 ++
 lldb/source/API/SBValue.cpp                   | 49 ++++++++++++++++--
 lldb/source/Target/Target.cpp                 | 22 ++++++++
 lldb/source/Target/TargetProperties.td        |  3 ++
 .../expr/CreateValueFromExpression/Makefile   |  3 ++
 .../TestCreateValueFromExpression.py          | 51 +++++++++++++++++++
 .../expr/CreateValueFromExpression/main.cpp   |  7 +++
 7 files changed, 134 insertions(+), 5 deletions(-)
 create mode 100644 
lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/TestCreateValueFromExpression.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/main.cpp

diff --git a/lldb/include/lldb/Target/Target.h 
b/lldb/include/lldb/Target/Target.h
index 31a59a8501338..6ee72bf0d288b 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -281,6 +281,10 @@ class TargetProperties : public Properties {
 
   void SetUseDIL(ExecutionContext *exe_ctx, bool b);
 
+  bool GetUseDILForCreatingValues() const;
+
+  void SetUseDILForCreatingValues(bool b);
+
   void SetRequireHardwareBreakpoints(bool b);
 
   bool GetRequireHardwareBreakpoints() const;
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 32fbe1ecf15b0..822e18df7d199 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -473,18 +473,57 @@ lldb::SBValue SBValue::CreateValueFromExpression(const 
char *name,
                                                  SBExpressionOptions &options) 
{
   LLDB_INSTRUMENT_VA(this, name, expression, options);
 
-  lldb::SBValue sb_value;
+  lldb::ValueObjectSP new_value_sp;
+  StackFrameSP frame_sp(GetFrame().GetFrameSP());
+  TargetSP target_sp(GetTarget().GetSP());
+  // If enabled, attempt to use DIL to evaluate the expression.
+  bool DIL_success = false;
+  if (frame_sp && target_sp) {
+    bool use_DIL = target_sp->GetUseDILForCreatingValues();
+    if (use_DIL) {
+      Status error;
+      if (frame_sp) {
+        uint32_t expr_path_options =
+            StackFrame::eExpressionPathOptionCheckPtrVsMember |
+            StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
+        lldb::VariableSP var_sp;
+        new_value_sp = frame_sp->GetValueForVariableExpressionPath(
+            expression, eNoDynamicValues, expr_path_options, var_sp, error);
+      }
+      DIL_success = new_value_sp && new_value_sp->GetError().Success();
+    }
+  }
+
   ValueLocker locker;
   lldb::ValueObjectSP value_sp(GetSP(locker));
-  lldb::ValueObjectSP new_value_sp;
-  if (value_sp) {
+  // Fall back to full expression evaluation if DIL did not succeed.
+  if (!DIL_success && value_sp) {
     ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
     new_value_sp = value_sp->CreateChildValueObjectFromExpression(
         name, expression, exe_ctx, options.ref());
-    if (new_value_sp)
-      new_value_sp->SetName(name);
   }
+
+  if (new_value_sp)
+    new_value_sp->SetName(name);
+  lldb::SBValue sb_value;
   sb_value.SetSP(new_value_sp);
+
+  Log *log = GetLog(LLDBLog::Expressions);
+  if (new_value_sp && new_value_sp->GetError().Success())
+    LLDB_LOGF(log,
+              "** [SBValue::CreateValueFromExpression] Expression result: "
+              "(%s) %s = %s (evaluated by: %s) **",
+              new_value_sp->GetTypeName().GetCString(),
+              new_value_sp->GetName().GetCString(),
+              new_value_sp->GetValueAsCString(),
+              DIL_success ? "DIL" : "UserExpression");
+  else
+    LLDB_LOGF(log,
+              "** [SBValue::CreateValueFromExpression] Expression evaluation "
+              "failed: %s **",
+              new_value_sp ? new_value_sp->GetError().AsCString()
+                           : "unknown error");
+
   return sb_value;
 }
 
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 928292799be21..20c94d98eca56 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -5223,6 +5223,28 @@ void TargetProperties::SetUseDIL(ExecutionContext 
*exe_ctx, bool b) {
     exp_values->SetPropertyAtIndex(ePropertyUseDIL, true, exe_ctx);
 }
 
+bool TargetProperties::GetUseDILForCreatingValues() const {
+  const Property *exp_property =
+      m_collection_sp->GetPropertyAtIndex(ePropertyExperimental);
+  OptionValueProperties *exp_values =
+      exp_property->GetValue()->GetAsProperties();
+  if (exp_values)
+    return exp_values
+        ->GetPropertyAtIndexAs<bool>(ePropertyUseDILForCreatingValues)
+        .value_or(false);
+  else
+    return true;
+}
+
+void TargetProperties::SetUseDILForCreatingValues(bool b) {
+  const Property *exp_property =
+      m_collection_sp->GetPropertyAtIndex(ePropertyExperimental);
+  OptionValueProperties *exp_values =
+      exp_property->GetValue()->GetAsProperties();
+  if (exp_values)
+    exp_values->SetPropertyAtIndex(ePropertyUseDILForCreatingValues, b);
+}
+
 ArchSpec TargetProperties::GetDefaultArchitecture() const {
   const uint32_t idx = ePropertyDefaultArch;
   return GetPropertyAtIndexAs<ArchSpec>(idx, {});
diff --git a/lldb/source/Target/TargetProperties.td 
b/lldb/source/Target/TargetProperties.td
index 7b296da45b26e..3d717fe334b44 100644
--- a/lldb/source/Target/TargetProperties.td
+++ b/lldb/source/Target/TargetProperties.td
@@ -7,6 +7,9 @@ let Definition = "target_experimental", Path = 
"target.experimental" in {
   def UseDIL : Property<"use-DIL", "Boolean">,
     Global, DefaultTrue,
     Desc<"If true, use the DIL implementation for frame variable evaluation.">;
+  def UseDILForCreatingValues: Property<"use-DIL-for-creating-values", 
"Boolean">,
+    Global, DefaultTrue,
+    Desc<"If true, use the DIL implementation to create variables from 
expressions.">;
 }
 
 let Definition = "target", Path = "target" in {
diff --git 
a/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/Makefile 
b/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ 
b/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git 
a/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/TestCreateValueFromExpression.py
 
b/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/TestCreateValueFromExpression.py
new file mode 100644
index 0000000000000..bfc202c96772f
--- /dev/null
+++ 
b/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/TestCreateValueFromExpression.py
@@ -0,0 +1,51 @@
+"""
+Test how DIL is used in SBValue::CreateValueFromExpression.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+
+class TestCreateValueFromExpression(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def test_formatter(self):
+        self.build()
+        (_, _, thread, _) = lldbutil.run_to_source_breakpoint(
+            self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+        )
+
+        # Enable logging
+        log_file = self.getBuildArtifact("log-file.txt")
+        if os.path.exists(log_file):
+            os.remove(log_file)
+        self.runCmd("log enable -f '%s' lldb expr" % (log_file))
+
+        self.runCmd("settings set target.experimental.use-DIL true")
+        self.runCmd("settings set 
target.experimental.use-DIL-for-creating-values true")
+
+        # Check expression results
+        frame = thread.GetFrameAtIndex(0)
+        i = frame.FindVariable("i")
+        v1 = i.CreateValueFromExpression("v1", "i + 1")
+        self.assertEqual(v1.GetValue(), "1")
+        v2 = i.CreateValueFromExpression("v2", "static_cast<double>(i) + 2.5")
+        self.assertEqual(v2.GetValue(), "2.5")
+        self.runCmd(
+            "settings set target.experimental.use-DIL-for-creating-values 
false"
+        )
+        v3 = i.CreateValueFromExpression("v3", "i + 3")
+        self.assertEqual(v3.GetValue(), "3")
+
+        with open(log_file, "r") as f:
+            log = f.read()
+
+        # Check that supported expression is evaluated by DIL
+        self.assertGreater(log.find("v1 = 1 (evaluated by: DIL)"), 0)
+        # Check that if DIL cannot evaluate the expression, it falls back to
+        # full expression evaluation
+        self.assertGreater(log.find("v2 = 2.5 (evaluated by: 
UserExpression)"), 0)
+        # Check that creating values using DIL was disabled for the 3rd 
expression
+        self.assertGreater(log.find("v3 = 3 (evaluated by: UserExpression)"), 
0)
diff --git 
a/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/main.cpp 
b/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/main.cpp
new file mode 100644
index 0000000000000..0435ca02d5605
--- /dev/null
+++ 
b/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/main.cpp
@@ -0,0 +1,7 @@
+void stop() {}
+
+int main() {
+  int i = 0;
+
+  stop(); // Set a breakpoint here
+}

>From a84f9142a88933bc8a12b62106f4254cd665b98e Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Wed, 9 Sep 2026 21:00:02 +0500
Subject: [PATCH 2/5] Remove a check, pass the dynamic value option

---
 lldb/source/API/SBValue.cpp | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 822e18df7d199..1d1263060ff69 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -482,14 +482,13 @@ lldb::SBValue SBValue::CreateValueFromExpression(const 
char *name,
     bool use_DIL = target_sp->GetUseDILForCreatingValues();
     if (use_DIL) {
       Status error;
-      if (frame_sp) {
-        uint32_t expr_path_options =
-            StackFrame::eExpressionPathOptionCheckPtrVsMember |
-            StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
-        lldb::VariableSP var_sp;
-        new_value_sp = frame_sp->GetValueForVariableExpressionPath(
-            expression, eNoDynamicValues, expr_path_options, var_sp, error);
-      }
+      uint32_t expr_path_options =
+          StackFrame::eExpressionPathOptionCheckPtrVsMember |
+          StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
+      lldb::VariableSP var_sp;
+      new_value_sp = frame_sp->GetValueForVariableExpressionPath(
+          expression, options.GetFetchDynamicValue(), expr_path_options, 
var_sp,
+          error);
       DIL_success = new_value_sp && new_value_sp->GetError().Success();
     }
   }

>From 6b6088bcae4524a0c26a81a418048bbaf6c6a435 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Wed, 9 Sep 2026 21:51:07 +0500
Subject: [PATCH 3/5] Add comments and documentation

---
 lldb/bindings/interface/SBValueDocstrings.i | 9 +++++++++
 lldb/include/lldb/API/SBValue.h             | 6 ++++++
 lldb/source/Target/TargetProperties.td      | 2 +-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/lldb/bindings/interface/SBValueDocstrings.i 
b/lldb/bindings/interface/SBValueDocstrings.i
index 627036b6c0c66..08e697e2bf7b2 100644
--- a/lldb/bindings/interface/SBValueDocstrings.i
+++ b/lldb/bindings/interface/SBValueDocstrings.i
@@ -230,3 +230,12 @@ linked list."
     or a constant. A success result does not guarantee a write will succeed;
     other runtime conditions may still prevent a successful write."
 ) lldb::SBValue::CanSet;
+
+%feature("docstring", "
+    Create an SBValue with the given name by evaluating the expression, with
+    the execution context inherited from the current SBValue.
+    Data Inspection Language (DIL) attempts to evaluate the expression first
+    (can be disabled by setting target.experimental.use-DIL-for-creating-values
+    to false). If DIL is not called or fails, the evaluation falls back to
+    UserExpression."
+) lldb::SBValue::CreateValueFromExpression;
diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index bbaa28762328e..fe2b90e305196 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -165,6 +165,12 @@ class LLDB_API SBValue {
   LLDB_DEPRECATED("Use the expression evaluator to perform type casting")
   lldb::SBValue Cast(lldb::SBType type);
 
+  /// Create an SBValue with the given name by evaluating the expression, with
+  /// the execution context inherited from the current SBValue.
+  /// Data Inspection Language (DIL) attempts to evaluate the expression first
+  /// (can be disabled by target.experimental.use-DIL-for-creating-values)
+  /// If DIL is not called or fails, the evaluation falls back to
+  /// UserExpression.
   lldb::SBValue CreateValueFromExpression(const char *name,
                                           const char *expression);
 
diff --git a/lldb/source/Target/TargetProperties.td 
b/lldb/source/Target/TargetProperties.td
index 3d717fe334b44..4ba6791e3183d 100644
--- a/lldb/source/Target/TargetProperties.td
+++ b/lldb/source/Target/TargetProperties.td
@@ -9,7 +9,7 @@ let Definition = "target_experimental", Path = 
"target.experimental" in {
     Desc<"If true, use the DIL implementation for frame variable evaluation.">;
   def UseDILForCreatingValues: Property<"use-DIL-for-creating-values", 
"Boolean">,
     Global, DefaultTrue,
-    Desc<"If true, use the DIL implementation to create variables from 
expressions.">;
+    Desc<"If true, use the DIL implementation in API 
SBValue::CreateValueFromExpression.">;
 }
 
 let Definition = "target", Path = "target" in {

>From 1bf67a332449dba260d9fd6b9f7a124722c3e8f3 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Fri, 11 Sep 2026 21:01:05 +0500
Subject: [PATCH 4/5] Add a DIL option to SBExpressionOptions and use it

---
 lldb/include/lldb/API/SBExpressionOptions.h      |  4 ++++
 lldb/include/lldb/Target/Target.h                |  8 ++++++++
 lldb/source/API/SBExpressionOptions.cpp          | 12 ++++++++++++
 lldb/source/API/SBValue.cpp                      |  6 ++++--
 .../TestCreateValueFromExpression.py             | 16 +++++++++++++---
 5 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/lldb/include/lldb/API/SBExpressionOptions.h 
b/lldb/include/lldb/API/SBExpressionOptions.h
index 8dcd6ea8e511a..96adc084d86f1 100644
--- a/lldb/include/lldb/API/SBExpressionOptions.h
+++ b/lldb/include/lldb/API/SBExpressionOptions.h
@@ -115,6 +115,10 @@ class LLDB_API SBExpressionOptions {
 
   SBError SetBooleanLanguageOption(const char *option_name, bool value);
 
+  bool GetTryDILFirst();
+
+  void SetTryDILFirst(bool b = true);
+
 protected:
   lldb_private::EvaluateExpressionOptions *get() const;
 
diff --git a/lldb/include/lldb/Target/Target.h 
b/lldb/include/lldb/Target/Target.h
index 6ee72bf0d288b..0b4290ad4a33d 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -534,6 +534,10 @@ class EvaluateExpressionOptions {
 
   bool GetCppIgnoreContextQualifiers() const;
 
+  void SetTryDILFirst(bool b) { m_try_DIL_first = b; }
+
+  bool GetTryDILFirst() const { return m_try_DIL_first; }
+
 private:
   const StructuredData::Dictionary &GetLanguageOptions() const;
 
@@ -560,6 +564,10 @@ class EvaluateExpressionOptions {
   /// True if the executed code should be treated as utility code that is only
   /// used by LLDB internally.
   bool m_running_utility_expression = false;
+  /// If enabled, Data Inspection Language (DIL) should attempt to evaluate the
+  /// expression first. If DIL is not called or fails, the evaluation falls
+  /// back to UserExpression.
+  bool m_try_DIL_first = false;
 
   lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues;
   Timeout<std::micro> m_timeout = default_timeout;
diff --git a/lldb/source/API/SBExpressionOptions.cpp 
b/lldb/source/API/SBExpressionOptions.cpp
index 7786daa98d1cb..36afca66debfe 100644
--- a/lldb/source/API/SBExpressionOptions.cpp
+++ b/lldb/source/API/SBExpressionOptions.cpp
@@ -301,6 +301,18 @@ SBError 
SBExpressionOptions::SetBooleanLanguageOption(const char *option_name,
   return error;
 }
 
+bool SBExpressionOptions::GetTryDILFirst() {
+  LLDB_INSTRUMENT_VA(this);
+
+  return m_opaque_up->GetTryDILFirst();
+}
+
+void SBExpressionOptions::SetTryDILFirst(bool b) {
+  LLDB_INSTRUMENT_VA(this, b);
+
+  return m_opaque_up->SetTryDILFirst(b);
+}
+
 EvaluateExpressionOptions *SBExpressionOptions::get() const {
   return m_opaque_up.get();
 }
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 1d1263060ff69..449cafb85ef64 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -465,6 +465,9 @@ lldb::SBValue SBValue::CreateValueFromExpression(const char 
*name,
 
   SBExpressionOptions options;
   options.ref().SetKeepInMemory(true);
+  TargetSP target_sp(GetTarget().GetSP());
+  if (target_sp)
+    options.SetTryDILFirst(target_sp->GetUseDILForCreatingValues());
   return CreateValueFromExpression(name, expression, options);
 }
 
@@ -479,8 +482,7 @@ lldb::SBValue SBValue::CreateValueFromExpression(const char 
*name,
   // If enabled, attempt to use DIL to evaluate the expression.
   bool DIL_success = false;
   if (frame_sp && target_sp) {
-    bool use_DIL = target_sp->GetUseDILForCreatingValues();
-    if (use_DIL) {
+    if (options.GetTryDILFirst()) {
       Status error;
       uint32_t expr_path_options =
           StackFrame::eExpressionPathOptionCheckPtrVsMember |
diff --git 
a/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/TestCreateValueFromExpression.py
 
b/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/TestCreateValueFromExpression.py
index bfc202c96772f..f105adc87ac14 100644
--- 
a/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/TestCreateValueFromExpression.py
+++ 
b/lldb/test/API/commands/frame/var-dil/expr/CreateValueFromExpression/TestCreateValueFromExpression.py
@@ -33,11 +33,17 @@ def test_formatter(self):
         self.assertEqual(v1.GetValue(), "1")
         v2 = i.CreateValueFromExpression("v2", "static_cast<double>(i) + 2.5")
         self.assertEqual(v2.GetValue(), "2.5")
+        expr_options = lldb.SBExpressionOptions()
+        v3 = i.CreateValueFromExpression("v3", "i + 3", expr_options)
+        self.assertEqual(v3.GetValue(), "3")
         self.runCmd(
             "settings set target.experimental.use-DIL-for-creating-values 
false"
         )
-        v3 = i.CreateValueFromExpression("v3", "i + 3")
-        self.assertEqual(v3.GetValue(), "3")
+        v4 = i.CreateValueFromExpression("v4", "i + 4")
+        self.assertEqual(v4.GetValue(), "4")
+        expr_options.SetTryDILFirst(True)
+        v5 = i.CreateValueFromExpression("v5", "i + 5", expr_options)
+        self.assertEqual(v5.GetValue(), "5")
 
         with open(log_file, "r") as f:
             log = f.read()
@@ -47,5 +53,9 @@ def test_formatter(self):
         # Check that if DIL cannot evaluate the expression, it falls back to
         # full expression evaluation
         self.assertGreater(log.find("v2 = 2.5 (evaluated by: 
UserExpression)"), 0)
-        # Check that creating values using DIL was disabled for the 3rd 
expression
+        # Check that trying DIL can be disabled through expression options 
parameter
         self.assertGreater(log.find("v3 = 3 (evaluated by: UserExpression)"), 
0)
+        # Check that using DIL was disabled after disabling the lldb setting
+        self.assertGreater(log.find("v4 = 4 (evaluated by: UserExpression)"), 
0)
+        # Check that trying DIL can be enabled through expression options 
parameter
+        self.assertGreater(log.find("v5 = 5 (evaluated by: DIL)"), 0)

>From 641cbed0644f828ab64a8a05e50b3b51228887ec Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Sat, 12 Sep 2026 18:07:59 +0500
Subject: [PATCH 5/5] Remove unused return

---
 lldb/source/API/SBExpressionOptions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/API/SBExpressionOptions.cpp 
b/lldb/source/API/SBExpressionOptions.cpp
index 36afca66debfe..9fbd1c70f9d57 100644
--- a/lldb/source/API/SBExpressionOptions.cpp
+++ b/lldb/source/API/SBExpressionOptions.cpp
@@ -310,7 +310,7 @@ bool SBExpressionOptions::GetTryDILFirst() {
 void SBExpressionOptions::SetTryDILFirst(bool b) {
   LLDB_INSTRUMENT_VA(this, b);
 
-  return m_opaque_up->SetTryDILFirst(b);
+  m_opaque_up->SetTryDILFirst(b);
 }
 
 EvaluateExpressionOptions *SBExpressionOptions::get() const {

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to