[Lldb-commits] [lldb] [lldb] Add `nullptr` literal to DIL (PR #208831)
Ilia Kuklin via lldb-commits
lldb-commits at lists.llvm.org
Wed Jul 15 04:10:11 PDT 2026
https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/208831
>From 695a10c5fdf704858e0a05def1f7a9271ca1b21d Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Wed, 24 Sep 2025 21:28:24 +0500
Subject: [PATCH 1/3] [lldb] Add nullptr literal to DIL
---
lldb/docs/dil-expr-lang.ebnf | 2 ++
lldb/include/lldb/ValueObject/DILAST.h | 15 +++++++++++++++
lldb/include/lldb/ValueObject/DILEval.h | 2 ++
lldb/include/lldb/ValueObject/DILLexer.h | 1 +
lldb/include/lldb/ValueObject/DILParser.h | 1 +
lldb/source/ValueObject/DILAST.cpp | 5 +++++
lldb/source/ValueObject/DILEval.cpp | 14 ++++++++++++++
lldb/source/ValueObject/DILLexer.cpp | 3 +++
lldb/source/ValueObject/DILParser.cpp | 14 ++++++++++++++
.../expr/Literals/TestFrameVarDILLiterals.py | 9 ++++++++-
10 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/lldb/docs/dil-expr-lang.ebnf b/lldb/docs/dil-expr-lang.ebnf
index fce8f4461b46f..5571d682c8761 100644
--- a/lldb/docs/dil-expr-lang.ebnf
+++ b/lldb/docs/dil-expr-lang.ebnf
@@ -57,6 +57,8 @@ numeric_literal = ? Integer constant: hexademical, decimal, octal, binary ?
boolean_literal = "true" | "false" ;
+pointer_literal = "nullptr" ;
+
register = "$" ? Register name ? ;
nested_name_specifier = type_name "::"
diff --git a/lldb/include/lldb/ValueObject/DILAST.h b/lldb/include/lldb/ValueObject/DILAST.h
index 93310a91a15bb..440f1e621b7aa 100644
--- a/lldb/include/lldb/ValueObject/DILAST.h
+++ b/lldb/include/lldb/ValueObject/DILAST.h
@@ -29,6 +29,7 @@ enum class NodeKind {
eIdentifierNode,
eIntegerLiteralNode,
eMemberOfNode,
+ ePointerLiteralNode,
eUnaryOpNode,
};
@@ -297,6 +298,18 @@ class BooleanLiteralNode : public ASTNode {
bool m_value;
};
+class PointerLiteralNode : public ASTNode {
+public:
+ PointerLiteralNode(uint32_t location)
+ : ASTNode(location, NodeKind::ePointerLiteralNode) {}
+
+ llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
+
+ static bool classof(const ASTNode &node) {
+ return node.GetKind() == NodeKind::ePointerLiteralNode;
+ }
+};
+
class CastNode : public ASTNode {
public:
CastNode(uint32_t location, CompilerType type, ASTNodeUP operand,
@@ -345,6 +358,8 @@ class Visitor {
Visit(const FloatLiteralNode &node) = 0;
virtual llvm::Expected<lldb::ValueObjectSP>
Visit(const BooleanLiteralNode &node) = 0;
+ virtual llvm::Expected<lldb::ValueObjectSP>
+ Visit(const PointerLiteralNode &node) = 0;
virtual llvm::Expected<lldb::ValueObjectSP> Visit(const CastNode &node) = 0;
};
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
index 35784ea9987f9..da94b1f99005b 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -72,6 +72,8 @@ class Interpreter : Visitor {
Visit(const FloatLiteralNode &node) override;
llvm::Expected<lldb::ValueObjectSP>
Visit(const BooleanLiteralNode &node) override;
+ llvm::Expected<lldb::ValueObjectSP>
+ Visit(const PointerLiteralNode &node) override;
llvm::Expected<lldb::ValueObjectSP> Visit(const CastNode &node) override;
/// Perform usual unary conversions on a value. At the moment this
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index f9f42dc59b311..4419e9c1d99b6 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -37,6 +37,7 @@ class Token {
integer_constant,
kw_false,
kw_true,
+ kw_nullptr,
l_paren,
l_square,
lessless,
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
index 9e2bbff4b6614..f8730cd499314 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -99,6 +99,7 @@ class DILParser {
ASTNodeUP ParseIntegerLiteral();
ASTNodeUP ParseFloatingPointLiteral();
ASTNodeUP ParseBooleanLiteral();
+ ASTNodeUP ParsePointerLiteral();
ASTNodeUP ParseCastExpression();
std::optional<CompilerType> ParseBuiltinType();
diff --git a/lldb/source/ValueObject/DILAST.cpp b/lldb/source/ValueObject/DILAST.cpp
index 40bf07bdd5aab..dab69dd31e248 100644
--- a/lldb/source/ValueObject/DILAST.cpp
+++ b/lldb/source/ValueObject/DILAST.cpp
@@ -83,6 +83,11 @@ BooleanLiteralNode::Accept(Visitor *v) const {
return v->Visit(*this);
}
+llvm::Expected<lldb::ValueObjectSP>
+PointerLiteralNode::Accept(Visitor *v) const {
+ return v->Visit(*this);
+}
+
llvm::Expected<lldb::ValueObjectSP> CastNode::Accept(Visitor *v) const {
return v->Visit(*this);
}
diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp
index 5fc2376be0e75..82898be83566f 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -1382,6 +1382,20 @@ Interpreter::Visit(const BooleanLiteralNode &node) {
value, "result");
}
+llvm::Expected<lldb::ValueObjectSP>
+Interpreter::Visit(const PointerLiteralNode &node) {
+ llvm::Expected<lldb::TypeSystemSP> type_system =
+ GetTypeSystemFromCU(m_stack_frame);
+ if (!type_system)
+ return type_system.takeError();
+ type_system.get()->GetPointerByteSize();
+ llvm::APInt ptr_value(type_system.get()->GetPointerByteSize() * CHAR_BIT, 0);
+ Scalar scalar(ptr_value);
+ CompilerType type = GetBasicType(*type_system, lldb::eBasicTypeNullPtr);
+ return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar, type,
+ "result");
+}
+
llvm::Expected<CastKind>
Interpreter::VerifyArithmeticCast(CompilerType source_type,
CompilerType target_type, int location) {
diff --git a/lldb/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
index 997ba6b09f872..17ffdcbf13b60 100644
--- a/lldb/source/ValueObject/DILLexer.cpp
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -44,6 +44,8 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
return "false";
case Kind::kw_true:
return "true";
+ case Token::kw_nullptr:
+ return "nullptr";
case Kind::l_paren:
return "l_paren";
case Kind::l_square:
@@ -190,6 +192,7 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
Token::Kind kind = llvm::StringSwitch<Token::Kind>(word)
.Case("false", Token::kw_false)
.Case("true", Token::kw_true)
+ .Case("nullptr", Token::kw_nullptr)
.Default(Token::identifier);
return Token(kind, word.str(), position);
}
diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp
index b55b12a2bc42a..af266d5561c53 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -391,6 +391,8 @@ ASTNodeUP DILParser::ParsePrimaryExpression() {
return ParseNumericLiteral();
if (CurToken().IsOneOf({Token::kw_true, Token::kw_false}))
return ParseBooleanLiteral();
+ if (CurToken().Is(Token::kw_nullptr))
+ return ParsePointerLiteral();
if (CurToken().IsOneOf(
{Token::coloncolon, Token::identifier, Token::l_paren})) {
// Save the source location for the diagnostics message.
@@ -844,6 +846,18 @@ ASTNodeUP DILParser::ParseFloatingPointLiteral() {
return std::make_unique<ErrorNode>();
}
+// Parse a pointer_literal.
+//
+// pointer_literal:
+// "nullptr"
+//
+ASTNodeUP DILParser::ParsePointerLiteral() {
+ Expect(Token::kw_nullptr);
+ uint32_t loc = CurToken().GetLocation();
+ m_dil_lexer.Advance();
+ return std::make_unique<PointerLiteralNode>(loc);
+}
+
void DILParser::Expect(Token::Kind kind) {
if (CurToken().IsNot(kind)) {
BailOut(llvm::formatv("expected {0}, got: {1}", kind, CurToken()),
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..80494534e5863 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 parsing
+ 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()
>From 5552d17165962e6bf3950f444a33cf94d18415eb Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Tue, 14 Jul 2026 19:55:21 +0500
Subject: [PATCH 2/3] Resolve 'nullptr' after searching identifiers
---
lldb/docs/dil-expr-lang.ebnf | 5 ++--
lldb/include/lldb/ValueObject/DILAST.h | 15 ----------
lldb/include/lldb/ValueObject/DILEval.h | 2 --
lldb/include/lldb/ValueObject/DILLexer.h | 1 -
lldb/include/lldb/ValueObject/DILParser.h | 1 -
lldb/source/ValueObject/DILAST.cpp | 5 ----
lldb/source/ValueObject/DILEval.cpp | 29 ++++++++++---------
lldb/source/ValueObject/DILLexer.cpp | 3 --
lldb/source/ValueObject/DILParser.cpp | 14 ---------
.../expr/Literals/TestFrameVarDILLiterals.py | 2 +-
10 files changed, 19 insertions(+), 58 deletions(-)
diff --git a/lldb/docs/dil-expr-lang.ebnf b/lldb/docs/dil-expr-lang.ebnf
index 5571d682c8761..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,7 +58,7 @@ numeric_literal = ? Integer constant: hexademical, decimal, octal, binary ?
boolean_literal = "true" | "false" ;
-pointer_literal = "nullptr" ;
+null_pointer = "nullptr" ;
register = "$" ? Register name ? ;
diff --git a/lldb/include/lldb/ValueObject/DILAST.h b/lldb/include/lldb/ValueObject/DILAST.h
index 440f1e621b7aa..93310a91a15bb 100644
--- a/lldb/include/lldb/ValueObject/DILAST.h
+++ b/lldb/include/lldb/ValueObject/DILAST.h
@@ -29,7 +29,6 @@ enum class NodeKind {
eIdentifierNode,
eIntegerLiteralNode,
eMemberOfNode,
- ePointerLiteralNode,
eUnaryOpNode,
};
@@ -298,18 +297,6 @@ class BooleanLiteralNode : public ASTNode {
bool m_value;
};
-class PointerLiteralNode : public ASTNode {
-public:
- PointerLiteralNode(uint32_t location)
- : ASTNode(location, NodeKind::ePointerLiteralNode) {}
-
- llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
-
- static bool classof(const ASTNode &node) {
- return node.GetKind() == NodeKind::ePointerLiteralNode;
- }
-};
-
class CastNode : public ASTNode {
public:
CastNode(uint32_t location, CompilerType type, ASTNodeUP operand,
@@ -358,8 +345,6 @@ class Visitor {
Visit(const FloatLiteralNode &node) = 0;
virtual llvm::Expected<lldb::ValueObjectSP>
Visit(const BooleanLiteralNode &node) = 0;
- virtual llvm::Expected<lldb::ValueObjectSP>
- Visit(const PointerLiteralNode &node) = 0;
virtual llvm::Expected<lldb::ValueObjectSP> Visit(const CastNode &node) = 0;
};
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
index da94b1f99005b..35784ea9987f9 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -72,8 +72,6 @@ class Interpreter : Visitor {
Visit(const FloatLiteralNode &node) override;
llvm::Expected<lldb::ValueObjectSP>
Visit(const BooleanLiteralNode &node) override;
- llvm::Expected<lldb::ValueObjectSP>
- Visit(const PointerLiteralNode &node) override;
llvm::Expected<lldb::ValueObjectSP> Visit(const CastNode &node) override;
/// Perform usual unary conversions on a value. At the moment this
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index 4419e9c1d99b6..f9f42dc59b311 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -37,7 +37,6 @@ class Token {
integer_constant,
kw_false,
kw_true,
- kw_nullptr,
l_paren,
l_square,
lessless,
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
index f8730cd499314..9e2bbff4b6614 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -99,7 +99,6 @@ class DILParser {
ASTNodeUP ParseIntegerLiteral();
ASTNodeUP ParseFloatingPointLiteral();
ASTNodeUP ParseBooleanLiteral();
- ASTNodeUP ParsePointerLiteral();
ASTNodeUP ParseCastExpression();
std::optional<CompilerType> ParseBuiltinType();
diff --git a/lldb/source/ValueObject/DILAST.cpp b/lldb/source/ValueObject/DILAST.cpp
index dab69dd31e248..40bf07bdd5aab 100644
--- a/lldb/source/ValueObject/DILAST.cpp
+++ b/lldb/source/ValueObject/DILAST.cpp
@@ -83,11 +83,6 @@ BooleanLiteralNode::Accept(Visitor *v) const {
return v->Visit(*this);
}
-llvm::Expected<lldb::ValueObjectSP>
-PointerLiteralNode::Accept(Visitor *v) const {
- return v->Visit(*this);
-}
-
llvm::Expected<lldb::ValueObjectSP> CastNode::Accept(Visitor *v) const {
return v->Visit(*this);
}
diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp
index 82898be83566f..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());
@@ -1382,20 +1397,6 @@ Interpreter::Visit(const BooleanLiteralNode &node) {
value, "result");
}
-llvm::Expected<lldb::ValueObjectSP>
-Interpreter::Visit(const PointerLiteralNode &node) {
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
- if (!type_system)
- return type_system.takeError();
- type_system.get()->GetPointerByteSize();
- llvm::APInt ptr_value(type_system.get()->GetPointerByteSize() * CHAR_BIT, 0);
- Scalar scalar(ptr_value);
- CompilerType type = GetBasicType(*type_system, lldb::eBasicTypeNullPtr);
- return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar, type,
- "result");
-}
-
llvm::Expected<CastKind>
Interpreter::VerifyArithmeticCast(CompilerType source_type,
CompilerType target_type, int location) {
diff --git a/lldb/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
index 17ffdcbf13b60..997ba6b09f872 100644
--- a/lldb/source/ValueObject/DILLexer.cpp
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -44,8 +44,6 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
return "false";
case Kind::kw_true:
return "true";
- case Token::kw_nullptr:
- return "nullptr";
case Kind::l_paren:
return "l_paren";
case Kind::l_square:
@@ -192,7 +190,6 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
Token::Kind kind = llvm::StringSwitch<Token::Kind>(word)
.Case("false", Token::kw_false)
.Case("true", Token::kw_true)
- .Case("nullptr", Token::kw_nullptr)
.Default(Token::identifier);
return Token(kind, word.str(), position);
}
diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp
index af266d5561c53..b55b12a2bc42a 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -391,8 +391,6 @@ ASTNodeUP DILParser::ParsePrimaryExpression() {
return ParseNumericLiteral();
if (CurToken().IsOneOf({Token::kw_true, Token::kw_false}))
return ParseBooleanLiteral();
- if (CurToken().Is(Token::kw_nullptr))
- return ParsePointerLiteral();
if (CurToken().IsOneOf(
{Token::coloncolon, Token::identifier, Token::l_paren})) {
// Save the source location for the diagnostics message.
@@ -846,18 +844,6 @@ ASTNodeUP DILParser::ParseFloatingPointLiteral() {
return std::make_unique<ErrorNode>();
}
-// Parse a pointer_literal.
-//
-// pointer_literal:
-// "nullptr"
-//
-ASTNodeUP DILParser::ParsePointerLiteral() {
- Expect(Token::kw_nullptr);
- uint32_t loc = CurToken().GetLocation();
- m_dil_lexer.Advance();
- return std::make_unique<PointerLiteralNode>(loc);
-}
-
void DILParser::Expect(Token::Kind kind) {
if (CurToken().IsNot(kind)) {
BailOut(llvm::formatv("expected {0}, got: {1}", kind, CurToken()),
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 80494534e5863..9b1167545681b 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,7 +23,7 @@ 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 parsing
+ # Check nullptr identifier
frame = thread.GetFrameAtIndex(0)
nullptr = frame.GetValueForVariablePath("nullptr")
nullptr_value = "0x" + "00" * self.target().GetAddressByteSize()
>From a636e09c9446f003de875a20b6ff1ff2d9c60307 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Wed, 15 Jul 2026 16:07:16 +0500
Subject: [PATCH 3/3] Add a test for a nullptr variable
---
.../expr/Literals/TestFrameVarDILLiterals.py | 2 +-
.../frame/var-dil/expr/Literals/main.cpp | 4 +++-
.../frame/var-dil/expr/NullptrVar/Makefile | 4 ++++
.../NullptrVar/TestFrameVarDILNullptrVar.py | 24 +++++++++++++++++++
.../frame/var-dil/expr/NullptrVar/main.c | 7 ++++++
5 files changed, 39 insertions(+), 2 deletions(-)
create mode 100644 lldb/test/API/commands/frame/var-dil/expr/NullptrVar/Makefile
create mode 100644 lldb/test/API/commands/frame/var-dil/expr/NullptrVar/TestFrameVarDILNullptrVar.py
create mode 100644 lldb/test/API/commands/frame/var-dil/expr/NullptrVar/main.c
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 9b1167545681b..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,7 +23,7 @@ def test_literals(self):
self.expect_var_path("true", value="true", type="bool")
self.expect_var_path("false", value="false", type="bool")
- # Check nullptr identifier
+ # Check nullptr literal
frame = thread.GetFrameAtIndex(0)
nullptr = frame.GetValueForVariablePath("nullptr")
nullptr_value = "0x" + "00" * self.target().GetAddressByteSize()
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
+}
More information about the lldb-commits
mailing list