-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[LLDB] Add boolean literals to DIL. #157992
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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).
|
@llvm/pr-subscribers-lldb Author: None (cmtice) ChangesThis 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). Full diff: https://github.com/llvm/llvm-project/pull/157992.diff 9 Files Affected:
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
|
|
Can we add a couple of tests for these to |
Done. :-) |
JDevlieghere
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks pretty straightforward. LGTM.
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 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).