[LLDB] Add boolean literals to DIL. (#157992)

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).
This commit is contained in:
cmtice
2025-09-16 16:04:42 -07:00
committed by GitHub
parent 7c861bcedf
commit 9855d546a4
10 changed files with 82 additions and 3 deletions

View File

@@ -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 "::"

View File

@@ -20,6 +20,7 @@ namespace lldb_private::dil {
enum class NodeKind {
eArraySubscriptNode,
eBitExtractionNode,
eBooleanLiteralNode,
eErrorNode,
eFloatLiteralNode,
eIdentifierNode,
@@ -226,6 +227,23 @@ private:
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 @@ public:
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

View File

@@ -58,6 +58,8 @@ private:
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,

View File

@@ -31,6 +31,8 @@ public:
float_constant,
identifier,
integer_constant,
kw_false,
kw_true,
l_paren,
l_square,
minus,

View File

@@ -99,11 +99,14 @@ private:
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));

View File

@@ -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

View File

@@ -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

View File

@@ -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, "::"},

View File

@@ -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

View File

@@ -19,6 +19,10 @@ class TestFrameVarDILLiterals(TestBase):
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")