[Lldb-commits] [lldb] [LLDB] Add boolean literals to DIL. (PR #157992)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 11 14:01:40 PDT 2025
https://github.com/cmtice updated https://github.com/llvm/llvm-project/pull/157992
>From 097c19c6f7e76f0111155cbcc56ec14e5098dcee Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Wed, 10 Sep 2025 21:58:07 -0700
Subject: [PATCH 1/2] [LLDB] Add boolean literals to DIL.
This adds the ability to recognize (and create ValueObjects for)
boolean literals ("true", "false") to DIL. This is a preliminary
step to adding type casting (and also for the ternary op).
---
lldb/docs/dil-expr-lang.ebnf | 3 +++
lldb/include/lldb/ValueObject/DILAST.h | 20 ++++++++++++++++++
lldb/include/lldb/ValueObject/DILEval.h | 2 ++
lldb/include/lldb/ValueObject/DILLexer.h | 2 ++
lldb/include/lldb/ValueObject/DILParser.h | 3 +++
lldb/source/ValueObject/DILAST.cpp | 5 +++++
lldb/source/ValueObject/DILEval.cpp | 6 ++++++
lldb/source/ValueObject/DILLexer.cpp | 15 +++++++++++---
lldb/source/ValueObject/DILParser.cpp | 25 +++++++++++++++++++++++
9 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/lldb/docs/dil-expr-lang.ebnf b/lldb/docs/dil-expr-lang.ebnf
index 67328939ba420..70eda3bf40650 100644
--- a/lldb/docs/dil-expr-lang.ebnf
+++ b/lldb/docs/dil-expr-lang.ebnf
@@ -16,6 +16,7 @@ postfix_expression = primary_expression
| postfix_expression "->" id_expression ;
primary_expression = numeric_literal
+ | boolean_literal
| id_expression
| "(" expression ")" ;
@@ -35,6 +36,8 @@ integer_literal = ? Integer constant: hexademical, decimal, octal, binary ? ;
numeric_literal = ? Integer constant: hexademical, decimal, octal, binary ?
| ? Floating constant ? ;
+boolean_literal = "true" | "false" ;
+
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 1d10755c46e39..0f05d753f1b56 100644
--- a/lldb/include/lldb/ValueObject/DILAST.h
+++ b/lldb/include/lldb/ValueObject/DILAST.h
@@ -20,6 +20,7 @@ namespace lldb_private::dil {
enum class NodeKind {
eArraySubscriptNode,
eBitExtractionNode,
+ eBooleanLiteralNode,
eErrorNode,
eFloatLiteralNode,
eIdentifierNode,
@@ -226,6 +227,23 @@ class FloatLiteralNode : public ASTNode {
llvm::APFloat m_value;
};
+class BooleanLiteralNode : public ASTNode {
+public:
+ BooleanLiteralNode(uint32_t location, bool value)
+ : ASTNode(location, NodeKind::eBooleanLiteralNode), m_value(value) {}
+
+ llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
+
+ bool GetValue() const & { return m_value; }
+
+ static bool classof(const ASTNode *node) {
+ return node->GetKind() == NodeKind::eBooleanLiteralNode;
+ }
+
+private:
+ bool m_value;
+};
+
/// This class contains one Visit method for each specialized type of
/// DIL AST node. The Visit methods are used to dispatch a DIL AST node to
/// the correct function in the DIL expression evaluator for evaluating that
@@ -247,6 +265,8 @@ class Visitor {
Visit(const IntegerLiteralNode *node) = 0;
virtual llvm::Expected<lldb::ValueObjectSP>
Visit(const FloatLiteralNode *node) = 0;
+ virtual llvm::Expected<lldb::ValueObjectSP>
+ Visit(const BooleanLiteralNode *node) = 0;
};
} // namespace lldb_private::dil
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
index 5a48c2c989f4d..eab3218ff828f 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -58,6 +58,8 @@ class Interpreter : Visitor {
Visit(const IntegerLiteralNode *node) override;
llvm::Expected<lldb::ValueObjectSP>
Visit(const FloatLiteralNode *node) override;
+ llvm::Expected<lldb::ValueObjectSP>
+ Visit(const BooleanLiteralNode *node) override;
llvm::Expected<CompilerType>
PickIntegerType(lldb::TypeSystemSP type_system,
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index 4345e6ce7f26b..28b94a79c5902 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -31,6 +31,8 @@ class Token {
float_constant,
identifier,
integer_constant,
+ kw_false,
+ kw_true,
l_paren,
l_square,
minus,
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
index 90df109337dcf..d17ed66d9b3ee 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -99,11 +99,14 @@ class DILParser {
ASTNodeUP ParseNumericLiteral();
ASTNodeUP ParseIntegerLiteral();
ASTNodeUP ParseFloatingPointLiteral();
+ ASTNodeUP ParseBooleanLiteral();
void BailOut(const std::string &error, uint32_t loc, uint16_t err_len);
void Expect(Token::Kind kind);
+ void ExpectOneOf(std::vector<Token::Kind> kinds_vec);
+
void TentativeParsingRollback(uint32_t saved_idx) {
if (m_error)
llvm::consumeError(std::move(m_error));
diff --git a/lldb/source/ValueObject/DILAST.cpp b/lldb/source/ValueObject/DILAST.cpp
index 70564663a62cd..7ed34db6e20df 100644
--- a/lldb/source/ValueObject/DILAST.cpp
+++ b/lldb/source/ValueObject/DILAST.cpp
@@ -46,4 +46,9 @@ llvm::Expected<lldb::ValueObjectSP> FloatLiteralNode::Accept(Visitor *v) const {
return v->Visit(this);
}
+llvm::Expected<lldb::ValueObjectSP>
+BooleanLiteralNode::Accept(Visitor *v) const {
+ return v->Visit(this);
+}
+
} // namespace lldb_private::dil
diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp
index c6cf41ee9e9ee..a9dbfad298d05 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -602,4 +602,10 @@ Interpreter::Visit(const FloatLiteralNode *node) {
"result");
}
+llvm::Expected<lldb::ValueObjectSP>
+Interpreter::Visit(const BooleanLiteralNode *node) {
+ bool value = node->GetValue();
+ return ValueObject::CreateValueObjectFromBool(m_target, value, "result");
+}
+
} // namespace lldb_private::dil
diff --git a/lldb/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
index 0b2288a9d9230..e0202a2fe24cc 100644
--- a/lldb/source/ValueObject/DILLexer.cpp
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -34,6 +34,10 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
return "identifier";
case Kind::integer_constant:
return "integer_constant";
+ case Kind::kw_false:
+ return "false";
+ case Kind::kw_true:
+ return "true";
case Kind::l_paren:
return "l_paren";
case Kind::l_square:
@@ -42,7 +46,6 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
return "minus";
case Kind::period:
return "period";
- return "l_square";
case Kind::plus:
return "plus";
case Kind::r_paren:
@@ -137,8 +140,14 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
return Token(kind, maybe_number->str(), position);
}
std::optional<llvm::StringRef> maybe_word = IsWord(expr, remainder);
- if (maybe_word)
- return Token(Token::identifier, maybe_word->str(), position);
+ if (maybe_word) {
+ llvm::StringRef word = *maybe_word;
+ Token::Kind kind = llvm::StringSwitch<Token::Kind>(word)
+ .Case("false", Token::kw_false)
+ .Case("true", Token::kw_true)
+ .Default(Token::identifier);
+ return Token(kind, word.str(), position);
+ }
constexpr std::pair<Token::Kind, const char *> operators[] = {
{Token::amp, "&"}, {Token::arrow, "->"}, {Token::coloncolon, "::"},
diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp
index 8c4f7fdb25bea..566bcaf81094a 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -180,12 +180,15 @@ ASTNodeUP DILParser::ParsePostfixExpression() {
//
// primary_expression:
// numeric_literal
+// boolean_literal
// id_expression
// "(" expression ")"
//
ASTNodeUP DILParser::ParsePrimaryExpression() {
if (CurToken().IsOneOf({Token::integer_constant, Token::float_constant}))
return ParseNumericLiteral();
+ if (CurToken().IsOneOf({Token::kw_true, Token::kw_false}))
+ return ParseBooleanLiteral();
if (CurToken().IsOneOf(
{Token::coloncolon, Token::identifier, Token::l_paren})) {
// Save the source location for the diagnostics message.
@@ -336,6 +339,20 @@ std::string DILParser::ParseUnqualifiedId() {
return identifier;
}
+// Parse an boolean_literal.
+//
+// boolean_literal:
+// "true"
+// "false"
+//
+ASTNodeUP DILParser::ParseBooleanLiteral() {
+ ExpectOneOf(std::vector<Token::Kind>{Token::kw_true, Token::kw_false});
+ uint32_t loc = CurToken().GetLocation();
+ bool literal_value = CurToken().Is(Token::kw_true);
+ m_dil_lexer.Advance();
+ return std::make_unique<BooleanLiteralNode>(loc, literal_value);
+}
+
void DILParser::BailOut(const std::string &error, uint32_t loc,
uint16_t err_len) {
if (m_error)
@@ -444,4 +461,12 @@ void DILParser::Expect(Token::Kind kind) {
}
}
+void DILParser::ExpectOneOf(std::vector<Token::Kind> kinds_vec) {
+ if (!CurToken().IsOneOf(kinds_vec)) {
+ BailOut(llvm::formatv("expected any of ({0}), got: {1}",
+ llvm::iterator_range(kinds_vec), CurToken()),
+ CurToken().GetLocation(), CurToken().GetSpelling().length());
+ }
+}
+
} // namespace lldb_private::dil
>From f9465c12c782f950a026125fae6ec4127994a871 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Thu, 11 Sep 2025 14:00:37 -0700
Subject: [PATCH 2/2] Test for boolean literals in TestFramVarDILLiterals.py
---
.../frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py | 4 ++++
1 file changed, 4 insertions(+)
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 431ec2829bc75..ca3357cd683a0 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
@@ -19,6 +19,10 @@ def test_literals(self):
self.runCmd("settings set target.experimental.use-DIL true")
+ # Check boolean literals parsing
+ self.expect_var_path("true", value="true", type="bool")
+ self.expect_var_path("false", value="false", type="bool")
+
# Check number literals parsing
self.expect_var_path("1.0", value="1", type="double")
self.expect_var_path("1.0f", value="1", type="float")
More information about the lldb-commits
mailing list