Skip to content

Commit 9855d54

Browse files
authored
[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).
1 parent 7c861bc commit 9855d54

File tree

10 files changed

+82
-3
lines changed

10 files changed

+82
-3
lines changed

lldb/docs/dil-expr-lang.ebnf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ postfix_expression = primary_expression
1616
| postfix_expression "->" id_expression ;
1717
1818
primary_expression = numeric_literal
19+
| boolean_literal
1920
| id_expression
2021
| "(" expression ")" ;
2122
@@ -35,6 +36,8 @@ integer_literal = ? Integer constant: hexademical, decimal, octal, binary ? ;
3536
numeric_literal = ? Integer constant: hexademical, decimal, octal, binary ?
3637
| ? Floating constant ? ;
3738
39+
boolean_literal = "true" | "false" ;
40+
3841
register = "$" ? Register name ? ;
3942
4043
nested_name_specifier = type_name "::"

lldb/include/lldb/ValueObject/DILAST.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace lldb_private::dil {
2020
enum class NodeKind {
2121
eArraySubscriptNode,
2222
eBitExtractionNode,
23+
eBooleanLiteralNode,
2324
eErrorNode,
2425
eFloatLiteralNode,
2526
eIdentifierNode,
@@ -226,6 +227,23 @@ class FloatLiteralNode : public ASTNode {
226227
llvm::APFloat m_value;
227228
};
228229

230+
class BooleanLiteralNode : public ASTNode {
231+
public:
232+
BooleanLiteralNode(uint32_t location, bool value)
233+
: ASTNode(location, NodeKind::eBooleanLiteralNode), m_value(value) {}
234+
235+
llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
236+
237+
bool GetValue() const & { return m_value; }
238+
239+
static bool classof(const ASTNode *node) {
240+
return node->GetKind() == NodeKind::eBooleanLiteralNode;
241+
}
242+
243+
private:
244+
bool m_value;
245+
};
246+
229247
/// This class contains one Visit method for each specialized type of
230248
/// DIL AST node. The Visit methods are used to dispatch a DIL AST node to
231249
/// the correct function in the DIL expression evaluator for evaluating that
@@ -247,6 +265,8 @@ class Visitor {
247265
Visit(const IntegerLiteralNode *node) = 0;
248266
virtual llvm::Expected<lldb::ValueObjectSP>
249267
Visit(const FloatLiteralNode *node) = 0;
268+
virtual llvm::Expected<lldb::ValueObjectSP>
269+
Visit(const BooleanLiteralNode *node) = 0;
250270
};
251271

252272
} // namespace lldb_private::dil

lldb/include/lldb/ValueObject/DILEval.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class Interpreter : Visitor {
5858
Visit(const IntegerLiteralNode *node) override;
5959
llvm::Expected<lldb::ValueObjectSP>
6060
Visit(const FloatLiteralNode *node) override;
61+
llvm::Expected<lldb::ValueObjectSP>
62+
Visit(const BooleanLiteralNode *node) override;
6163

6264
llvm::Expected<CompilerType>
6365
PickIntegerType(lldb::TypeSystemSP type_system,

lldb/include/lldb/ValueObject/DILLexer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class Token {
3131
float_constant,
3232
identifier,
3333
integer_constant,
34+
kw_false,
35+
kw_true,
3436
l_paren,
3537
l_square,
3638
minus,

lldb/include/lldb/ValueObject/DILParser.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,14 @@ class DILParser {
9999
ASTNodeUP ParseNumericLiteral();
100100
ASTNodeUP ParseIntegerLiteral();
101101
ASTNodeUP ParseFloatingPointLiteral();
102+
ASTNodeUP ParseBooleanLiteral();
102103

103104
void BailOut(const std::string &error, uint32_t loc, uint16_t err_len);
104105

105106
void Expect(Token::Kind kind);
106107

108+
void ExpectOneOf(std::vector<Token::Kind> kinds_vec);
109+
107110
void TentativeParsingRollback(uint32_t saved_idx) {
108111
if (m_error)
109112
llvm::consumeError(std::move(m_error));

lldb/source/ValueObject/DILAST.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,9 @@ llvm::Expected<lldb::ValueObjectSP> FloatLiteralNode::Accept(Visitor *v) const {
4646
return v->Visit(this);
4747
}
4848

49+
llvm::Expected<lldb::ValueObjectSP>
50+
BooleanLiteralNode::Accept(Visitor *v) const {
51+
return v->Visit(this);
52+
}
53+
4954
} // namespace lldb_private::dil

lldb/source/ValueObject/DILEval.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,4 +602,10 @@ Interpreter::Visit(const FloatLiteralNode *node) {
602602
"result");
603603
}
604604

605+
llvm::Expected<lldb::ValueObjectSP>
606+
Interpreter::Visit(const BooleanLiteralNode *node) {
607+
bool value = node->GetValue();
608+
return ValueObject::CreateValueObjectFromBool(m_target, value, "result");
609+
}
610+
605611
} // namespace lldb_private::dil

lldb/source/ValueObject/DILLexer.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
3434
return "identifier";
3535
case Kind::integer_constant:
3636
return "integer_constant";
37+
case Kind::kw_false:
38+
return "false";
39+
case Kind::kw_true:
40+
return "true";
3741
case Kind::l_paren:
3842
return "l_paren";
3943
case Kind::l_square:
@@ -42,7 +46,6 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
4246
return "minus";
4347
case Kind::period:
4448
return "period";
45-
return "l_square";
4649
case Kind::plus:
4750
return "plus";
4851
case Kind::r_paren:
@@ -137,8 +140,14 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
137140
return Token(kind, maybe_number->str(), position);
138141
}
139142
std::optional<llvm::StringRef> maybe_word = IsWord(expr, remainder);
140-
if (maybe_word)
141-
return Token(Token::identifier, maybe_word->str(), position);
143+
if (maybe_word) {
144+
llvm::StringRef word = *maybe_word;
145+
Token::Kind kind = llvm::StringSwitch<Token::Kind>(word)
146+
.Case("false", Token::kw_false)
147+
.Case("true", Token::kw_true)
148+
.Default(Token::identifier);
149+
return Token(kind, word.str(), position);
150+
}
142151

143152
constexpr std::pair<Token::Kind, const char *> operators[] = {
144153
{Token::amp, "&"}, {Token::arrow, "->"}, {Token::coloncolon, "::"},

lldb/source/ValueObject/DILParser.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,15 @@ ASTNodeUP DILParser::ParsePostfixExpression() {
180180
//
181181
// primary_expression:
182182
// numeric_literal
183+
// boolean_literal
183184
// id_expression
184185
// "(" expression ")"
185186
//
186187
ASTNodeUP DILParser::ParsePrimaryExpression() {
187188
if (CurToken().IsOneOf({Token::integer_constant, Token::float_constant}))
188189
return ParseNumericLiteral();
190+
if (CurToken().IsOneOf({Token::kw_true, Token::kw_false}))
191+
return ParseBooleanLiteral();
189192
if (CurToken().IsOneOf(
190193
{Token::coloncolon, Token::identifier, Token::l_paren})) {
191194
// Save the source location for the diagnostics message.
@@ -336,6 +339,20 @@ std::string DILParser::ParseUnqualifiedId() {
336339
return identifier;
337340
}
338341

342+
// Parse an boolean_literal.
343+
//
344+
// boolean_literal:
345+
// "true"
346+
// "false"
347+
//
348+
ASTNodeUP DILParser::ParseBooleanLiteral() {
349+
ExpectOneOf(std::vector<Token::Kind>{Token::kw_true, Token::kw_false});
350+
uint32_t loc = CurToken().GetLocation();
351+
bool literal_value = CurToken().Is(Token::kw_true);
352+
m_dil_lexer.Advance();
353+
return std::make_unique<BooleanLiteralNode>(loc, literal_value);
354+
}
355+
339356
void DILParser::BailOut(const std::string &error, uint32_t loc,
340357
uint16_t err_len) {
341358
if (m_error)
@@ -444,4 +461,12 @@ void DILParser::Expect(Token::Kind kind) {
444461
}
445462
}
446463

464+
void DILParser::ExpectOneOf(std::vector<Token::Kind> kinds_vec) {
465+
if (!CurToken().IsOneOf(kinds_vec)) {
466+
BailOut(llvm::formatv("expected any of ({0}), got: {1}",
467+
llvm::iterator_range(kinds_vec), CurToken()),
468+
CurToken().GetLocation(), CurToken().GetSpelling().length());
469+
}
470+
}
471+
447472
} // namespace lldb_private::dil

lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ def test_literals(self):
1919

2020
self.runCmd("settings set target.experimental.use-DIL true")
2121

22+
# Check boolean literals parsing
23+
self.expect_var_path("true", value="true", type="bool")
24+
self.expect_var_path("false", value="false", type="bool")
25+
2226
# Check number literals parsing
2327
self.expect_var_path("1.0", value="1", type="double")
2428
self.expect_var_path("1.0f", value="1", type="float")

0 commit comments

Comments
 (0)