Author: Ilia Kuklin
Date: 2026-07-16T21:58:30+05:00
New Revision: 3736a7bed1baae7c4b461062f89ddd76f799480d

URL: 
https://github.com/llvm/llvm-project/commit/3736a7bed1baae7c4b461062f89ddd76f799480d
DIFF: 
https://github.com/llvm/llvm-project/commit/3736a7bed1baae7c4b461062f89ddd76f799480d.diff

LOG: [lldb] Add `nullptr` literal to DIL (#208831)

DIL will first attempt resolving `nullptr` as a variable, and if there
is none, `nullptr` will be resolved as a null pointer.

Added: 
    lldb/test/API/commands/frame/var-dil/expr/NullptrVar/Makefile
    
lldb/test/API/commands/frame/var-dil/expr/NullptrVar/TestFrameVarDILNullptrVar.py
    lldb/test/API/commands/frame/var-dil/expr/NullptrVar/main.c

Modified: 
    lldb/docs/dil-expr-lang.ebnf
    lldb/source/ValueObject/DILEval.cpp
    
lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py
    lldb/test/API/commands/frame/var-dil/expr/Literals/main.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/docs/dil-expr-lang.ebnf b/lldb/docs/dil-expr-lang.ebnf
index fce8f4461b46f..f3c465711e956 100644
--- a/lldb/docs/dil-expr-lang.ebnf
+++ b/lldb/docs/dil-expr-lang.ebnf
@@ -43,7 +43,8 @@ primary_expression = numeric_literal
 
 id_expression = unqualified_id
               | qualified_id
-              | register ;
+              | register
+              | null_pointer ;
 
 unqualified_id = identifier ;
 
@@ -57,6 +58,8 @@ numeric_literal = ? Integer constant: hexademical, decimal, 
octal, binary ?
 
 boolean_literal = "true" | "false" ;
 
+null_pointer = "nullptr" ;
+
 register = "$" ? Register name ? ;
 
 nested_name_specifier = type_name "::"

diff  --git a/lldb/source/ValueObject/DILEval.cpp 
b/lldb/source/ValueObject/DILEval.cpp
index 5fc2376be0e75..4c5ac96dccf74 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -459,6 +459,21 @@ Interpreter::Visit(const IdentifierNode &node) {
   if (!identifier)
     identifier = LookupEnumValue(node.GetName(), m_stack_frame);
 
+  if (!identifier && node.GetName() == "nullptr") {
+    // If we got a "nullptr" identifier, and there is no defined variable with
+    // this name, resolve it as a null pointer.
+    llvm::Expected<lldb::TypeSystemSP> type_system =
+        GetTypeSystemFromCU(m_stack_frame);
+    if (!type_system)
+      return type_system.takeError();
+    type_system.get()->GetPointerByteSize();
+    llvm::APInt value(type_system.get()->GetPointerByteSize() * CHAR_BIT, 0);
+    Scalar scalar(value);
+    CompilerType type = GetBasicType(*type_system, lldb::eBasicTypeNullPtr);
+    return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar, 
type,
+                                                    "result");
+  }
+
   if (!identifier) {
     std::string errMsg =
         llvm::formatv("use of undeclared identifier '{0}'", node.GetName());

diff  --git 
a/lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py 
b/lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py
index ca3357cd683a0..0fc6b58662536 100644
--- 
a/lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py
+++ 
b/lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py
@@ -23,6 +23,14 @@ def test_literals(self):
         self.expect_var_path("true", value="true", type="bool")
         self.expect_var_path("false", value="false", type="bool")
 
+        # Check nullptr literal
+        frame = thread.GetFrameAtIndex(0)
+        nullptr = frame.GetValueForVariablePath("nullptr")
+        nullptr_value = "0x" + "00" * self.target().GetAddressByteSize()
+        self.assertEqual(nullptr.GetValue(), nullptr_value)
+        nullptr_type = nullptr.GetType().GetName()
+        self.assertRegex(nullptr_type, "nullptr_t")
+
         # Check number literals parsing
         self.expect_var_path("1.0", value="1", type="double")
         self.expect_var_path("1.0f", value="1", type="float")
@@ -47,7 +55,6 @@ def test_literals(self):
         )
 
         # Check integer literal type edge cases 
(dil::Interpreter::PickIntegerType)
-        frame = thread.GetFrameAtIndex(0)
         v = frame.GetValueForVariablePath("argc")
         # Creating an SBType from a BasicType still requires any value from 
the frame
         int_size = v.GetType().GetBasicType(lldb.eBasicTypeInt).GetByteSize()

diff  --git a/lldb/test/API/commands/frame/var-dil/expr/Literals/main.cpp 
b/lldb/test/API/commands/frame/var-dil/expr/Literals/main.cpp
index c9bd8afb0d71d..25ff77d1c3395 100644
--- a/lldb/test/API/commands/frame/var-dil/expr/Literals/main.cpp
+++ b/lldb/test/API/commands/frame/var-dil/expr/Literals/main.cpp
@@ -1,3 +1,5 @@
+void stop() {}
+
 int main(int argc, char **argv) {
-  return 0; // Set a breakpoint here
+  stop(); // Set a breakpoint here
 }

diff  --git a/lldb/test/API/commands/frame/var-dil/expr/NullptrVar/Makefile 
b/lldb/test/API/commands/frame/var-dil/expr/NullptrVar/Makefile
new file mode 100644
index 0000000000000..d98ea94ed5484
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/expr/NullptrVar/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -std=c17
+
+include Makefile.rules

diff  --git 
a/lldb/test/API/commands/frame/var-dil/expr/NullptrVar/TestFrameVarDILNullptrVar.py
 
b/lldb/test/API/commands/frame/var-dil/expr/NullptrVar/TestFrameVarDILNullptrVar.py
new file mode 100644
index 0000000000000..0d89bfba55b39
--- /dev/null
+++ 
b/lldb/test/API/commands/frame/var-dil/expr/NullptrVar/TestFrameVarDILNullptrVar.py
@@ -0,0 +1,24 @@
+"""
+Test DIL nullptr variable resolution.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+
+class TestFrameVarDILNullptrVar(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def test_nullptrvar(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "Set a breakpoint here", lldb.SBFileSpec("main.c")
+        )
+
+        self.runCmd("settings set target.experimental.use-DIL true")
+
+        # Check that if there is a defined variable called "nullptr",
+        # it gets properly resolved into its value instead of a null pointer.
+        self.expect_var_path("nullptr", value="1", type="int")

diff  --git a/lldb/test/API/commands/frame/var-dil/expr/NullptrVar/main.c 
b/lldb/test/API/commands/frame/var-dil/expr/NullptrVar/main.c
new file mode 100644
index 0000000000000..bb443c38caf95
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/expr/NullptrVar/main.c
@@ -0,0 +1,7 @@
+int nullptr = 1;
+
+void stop() {}
+
+int main(int argc, char **argv) {
+  stop(); // Set a breakpoint here
+}


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

Reply via email to