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 <[email protected]> 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 <[email protected]> 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") _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
