Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lldb/docs/dil-expr-lang.ebnf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ postfix_expression = primary_expression
| postfix_expression "->" id_expression ;

primary_expression = numeric_literal
| boolean_literal
| id_expression
| "(" expression ")" ;

Expand All @@ -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 "::"
Expand Down
20 changes: 20 additions & 0 deletions lldb/include/lldb/ValueObject/DILAST.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace lldb_private::dil {
enum class NodeKind {
eArraySubscriptNode,
eBitExtractionNode,
eBooleanLiteralNode,
eErrorNode,
eFloatLiteralNode,
eIdentifierNode,
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/ValueObject/DILEval.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/ValueObject/DILLexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class Token {
float_constant,
identifier,
integer_constant,
kw_false,
kw_true,
l_paren,
l_square,
minus,
Expand Down
3 changes: 3 additions & 0 deletions lldb/include/lldb/ValueObject/DILParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
5 changes: 5 additions & 0 deletions lldb/source/ValueObject/DILAST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 6 additions & 0 deletions lldb/source/ValueObject/DILEval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
15 changes: 12 additions & 3 deletions lldb/source/ValueObject/DILLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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, "::"},
Expand Down
25 changes: 25 additions & 0 deletions lldb/source/ValueObject/DILParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Loading