mirror of
https://github.com/intel/llvm.git
synced 2026-01-19 17:45:07 +08:00
[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:
@@ -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 "::"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -31,6 +31,8 @@ public:
|
||||
float_constant,
|
||||
identifier,
|
||||
integer_constant,
|
||||
kw_false,
|
||||
kw_true,
|
||||
l_paren,
|
||||
l_square,
|
||||
minus,
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, "::"},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user