Skip to content

Commit b80eb87

Browse files
committed
Remove scalar literal node, store subscript index as APInt
1 parent 05da91b commit b80eb87

File tree

8 files changed

+45
-154
lines changed

8 files changed

+45
-154
lines changed

lldb/docs/dil-expr-lang.ebnf

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ unary_expression = unary_operator expression
1111
unary_operator = "*" | "&" ;
1212
1313
postfix_expression = primary_expression
14-
| postfix_expression "[" expression "]";
14+
| postfix_expression "[" integer_literal "]";
1515
16-
primary_expression = numeric_literal
17-
| id_expression
16+
primary_expression = id_expression
1817
| "(" expression ")";
1918
2019
id_expression = unqualified_id
@@ -28,7 +27,7 @@ qualified_id = ["::"] [nested_name_specifier] unqualified_id
2827
2928
identifier = ? C99 Identifier ? ;
3029
31-
numeric_literal = ? C99 Integer constant ? ;
30+
integer_literal = ? Integer constant: hexademical, decimal, octal, binary ? ;
3231
3332
register = "$" ? Register name ? ;
3433

lldb/include/lldb/ValueObject/DILAST.h

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,6 @@ class ErrorNode : public ASTNode {
7373
}
7474
};
7575

76-
class ScalarLiteralNode : public ASTNode {
77-
public:
78-
ScalarLiteralNode(uint32_t location, lldb::BasicType type, Scalar value)
79-
: ASTNode(location, NodeKind::eScalarLiteralNode), m_type(type),
80-
m_value(value) {}
81-
82-
llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
83-
84-
lldb::BasicType GetType() const { return m_type; }
85-
Scalar GetValue() const & { return m_value; }
86-
87-
static bool classof(const ASTNode *node) {
88-
return node->GetKind() == NodeKind::eScalarLiteralNode;
89-
}
90-
91-
private:
92-
lldb::BasicType m_type;
93-
Scalar m_value;
94-
};
95-
9676
class IdentifierNode : public ASTNode {
9777
public:
9878
IdentifierNode(uint32_t location, std::string name)
@@ -132,22 +112,22 @@ class UnaryOpNode : public ASTNode {
132112

133113
class ArraySubscriptNode : public ASTNode {
134114
public:
135-
ArraySubscriptNode(uint32_t location, ASTNodeUP lhs, ASTNodeUP rhs)
136-
: ASTNode(location, NodeKind::eArraySubscriptNode), m_lhs(std::move(lhs)),
137-
m_rhs(std::move(rhs)) {}
115+
ArraySubscriptNode(uint32_t location, ASTNodeUP base, llvm::APInt index)
116+
: ASTNode(location, NodeKind::eArraySubscriptNode),
117+
m_base(std::move(base)), m_index(std::move(index)) {}
138118

139119
llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
140120

141-
ASTNode *GetLHS() const { return m_lhs.get(); }
142-
ASTNode *GetRHS() const { return m_rhs.get(); }
121+
ASTNode *GetBase() const { return m_base.get(); }
122+
const llvm::APInt *GetIndex() const { return &m_index; }
143123

144124
static bool classof(const ASTNode *node) {
145125
return node->GetKind() == NodeKind::eArraySubscriptNode;
146126
}
147127

148128
private:
149-
ASTNodeUP m_lhs;
150-
ASTNodeUP m_rhs;
129+
ASTNodeUP m_base;
130+
llvm::APInt m_index;
151131
};
152132

153133
/// This class contains one Visit method for each specialized type of
@@ -158,8 +138,6 @@ class Visitor {
158138
public:
159139
virtual ~Visitor() = default;
160140
virtual llvm::Expected<lldb::ValueObjectSP>
161-
Visit(const ScalarLiteralNode *node) = 0;
162-
virtual llvm::Expected<lldb::ValueObjectSP>
163141
Visit(const IdentifierNode *node) = 0;
164142
virtual llvm::Expected<lldb::ValueObjectSP>
165143
Visit(const UnaryOpNode *node) = 0;

lldb/include/lldb/ValueObject/DILEval.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ class Interpreter : Visitor {
4747
llvm::Expected<lldb::ValueObjectSP> Evaluate(const ASTNode *node);
4848

4949
private:
50-
llvm::Expected<lldb::ValueObjectSP>
51-
Visit(const ScalarLiteralNode *node) override;
5250
llvm::Expected<lldb::ValueObjectSP>
5351
Visit(const IdentifierNode *node) override;
5452
llvm::Expected<lldb::ValueObjectSP> Visit(const UnaryOpNode *node) override;

lldb/include/lldb/ValueObject/DILParser.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ class DILParser {
9191

9292
std::string ParseIdExpression();
9393
std::string ParseUnqualifiedId();
94-
ASTNodeUP ParseNumericLiteral();
95-
ASTNodeUP ParseNumericConstant();
94+
std::optional<llvm::APInt> ParseIntegerConstant();
9695

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

lldb/source/ValueObject/DILAST.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ llvm::Expected<lldb::ValueObjectSP> ErrorNode::Accept(Visitor *v) const {
1515
llvm_unreachable("Attempting to Visit a DIL ErrorNode.");
1616
}
1717

18-
llvm::Expected<lldb::ValueObjectSP>
19-
ScalarLiteralNode::Accept(Visitor *v) const {
20-
return v->Visit(this);
21-
}
22-
2318
llvm::Expected<lldb::ValueObjectSP> IdentifierNode::Accept(Visitor *v) const {
2419
return v->Visit(this);
2520
}

lldb/source/ValueObject/DILEval.cpp

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -214,45 +214,6 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::Evaluate(const ASTNode *node) {
214214
return value_or_error;
215215
}
216216

217-
static CompilerType GetBasicType(std::shared_ptr<ExecutionContextScope> ctx,
218-
lldb::BasicType basic_type) {
219-
static std::unordered_map<lldb::BasicType, CompilerType> basic_types;
220-
auto type = basic_types.find(basic_type);
221-
if (type != basic_types.end()) {
222-
std::string type_name((type->second).GetTypeName().AsCString());
223-
// Only return the found type if it's valid.
224-
if (type_name != "<invalid>")
225-
return type->second;
226-
}
227-
228-
lldb::TargetSP target_sp = ctx->CalculateTarget();
229-
if (target_sp) {
230-
for (auto type_system_sp : target_sp->GetScratchTypeSystems())
231-
if (auto compiler_type =
232-
type_system_sp->GetBasicTypeFromAST(basic_type)) {
233-
basic_types.insert({basic_type, compiler_type});
234-
return compiler_type;
235-
}
236-
}
237-
CompilerType empty_type;
238-
return empty_type;
239-
}
240-
241-
llvm::Expected<lldb::ValueObjectSP>
242-
Interpreter::Visit(const ScalarLiteralNode *node) {
243-
CompilerType result_type = GetBasicType(m_exe_ctx_scope, node->GetType());
244-
Scalar value = node->GetValue();
245-
246-
if (result_type.IsInteger() || result_type.IsNullPtrType() ||
247-
result_type.IsPointerType()) {
248-
llvm::APInt val = value.GetAPSInt();
249-
return ValueObject::CreateValueObjectFromAPInt(m_target, val, result_type,
250-
"result");
251-
}
252-
253-
return lldb::ValueObjectSP();
254-
}
255-
256217
llvm::Expected<lldb::ValueObjectSP>
257218
Interpreter::Visit(const IdentifierNode *node) {
258219
lldb::DynamicValueType use_dynamic = m_default_dynamic;
@@ -313,36 +274,22 @@ Interpreter::Visit(const UnaryOpNode *node) {
313274

314275
llvm::Expected<lldb::ValueObjectSP>
315276
Interpreter::Visit(const ArraySubscriptNode *node) {
316-
auto lhs_or_err = Evaluate(node->GetLHS());
277+
auto lhs_or_err = Evaluate(node->GetBase());
317278
if (!lhs_or_err) {
318279
return lhs_or_err;
319280
}
320281
lldb::ValueObjectSP base = *lhs_or_err;
321-
auto rhs_or_err = Evaluate(node->GetRHS());
322-
if (!rhs_or_err) {
323-
return rhs_or_err;
324-
}
325-
lldb::ValueObjectSP index = *rhs_or_err;
282+
const llvm::APInt *index = node->GetIndex();
326283

327284
Status error;
328285
if (base->GetCompilerType().IsReferenceType()) {
329286
base = base->Dereference(error);
330287
if (error.Fail())
331288
return error.ToError();
332289
}
333-
if (index->GetCompilerType().IsReferenceType()) {
334-
index = index->Dereference(error);
335-
if (error.Fail())
336-
return error.ToError();
337-
}
338-
339-
auto index_type = index->GetCompilerType();
340-
if (!index_type.IsIntegerOrUnscopedEnumerationType())
341-
return llvm::make_error<DILDiagnosticError>(
342-
m_expr, "array subscript is not an integer", node->GetLocation());
343290

344291
// Check to see if 'base' has a synthetic value; if so, try using that.
345-
uint64_t child_idx = index->GetValueAsUnsigned(0);
292+
uint64_t child_idx = index->getZExtValue();
346293
if (base->HasSyntheticValue()) {
347294
lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
348295
if (synthetic && synthetic != base) {
@@ -384,7 +331,7 @@ Interpreter::Visit(const ArraySubscriptNode *node) {
384331
return base->GetChildAtIndex(child_idx);
385332
}
386333

387-
int64_t signed_child_idx = index->GetValueAsSigned(0);
334+
int64_t signed_child_idx = index->getSExtValue();
388335
return base->GetSyntheticArrayMember(signed_child_idx, true);
389336
}
390337

lldb/source/ValueObject/DILParser.cpp

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ ASTNodeUP DILParser::ParseUnaryExpression() {
118118
//
119119
// postfix_expression:
120120
// primary_expression
121-
// postfix_expression "[" expression "]"
121+
// postfix_expression "[" integer_literal "]"
122122
//
123123
ASTNodeUP DILParser::ParsePostfixExpression() {
124124
ASTNodeUP lhs = ParsePrimaryExpression();
@@ -128,11 +128,17 @@ ASTNodeUP DILParser::ParsePostfixExpression() {
128128
switch (token.GetKind()) {
129129
case Token::l_square: {
130130
m_dil_lexer.Advance();
131-
auto rhs = ParseExpression();
131+
auto rhs = ParseIntegerConstant();
132+
if (!rhs) {
133+
BailOut(
134+
llvm::formatv("failed to parse integer constant: {0}", CurToken()),
135+
CurToken().GetLocation(), CurToken().GetSpelling().length());
136+
return std::make_unique<ErrorNode>();
137+
}
132138
Expect(Token::r_square);
133139
m_dil_lexer.Advance();
134140
lhs = std::make_unique<ArraySubscriptNode>(loc, std::move(lhs),
135-
std::move(rhs));
141+
std::move(*rhs));
136142
break;
137143
}
138144
default:
@@ -150,8 +156,6 @@ ASTNodeUP DILParser::ParsePostfixExpression() {
150156
// "(" expression ")"
151157
//
152158
ASTNodeUP DILParser::ParsePrimaryExpression() {
153-
if (CurToken().Is(Token::numeric_constant))
154-
return ParseNumericLiteral();
155159
if (CurToken().IsOneOf({Token::coloncolon, Token::identifier})) {
156160
// Save the source location for the diagnostics message.
157161
uint32_t loc = CurToken().GetLocation();
@@ -311,50 +315,21 @@ void DILParser::BailOut(const std::string &error, uint32_t loc,
311315
m_dil_lexer.ResetTokenIdx(m_dil_lexer.NumLexedTokens() - 1);
312316
}
313317

314-
// Parse a numeric_literal.
318+
// Parse a integer_literal.
315319
//
316-
// numeric_literal:
317-
// ? Token::numeric_constant ?
320+
// integer_literal:
321+
// ? Integer constant ?
318322
//
319-
ASTNodeUP DILParser::ParseNumericLiteral() {
320-
Expect(Token::numeric_constant);
321-
ASTNodeUP numeric_constant = ParseNumericConstant();
322-
if (numeric_constant->GetKind() == NodeKind::eErrorNode) {
323-
BailOut(llvm::formatv("Failed to parse token as numeric-constant: {0}",
324-
CurToken()),
325-
CurToken().GetLocation(), CurToken().GetSpelling().length());
326-
return std::make_unique<ErrorNode>();
327-
}
328-
m_dil_lexer.Advance();
329-
return numeric_constant;
330-
}
331-
332-
static constexpr std::pair<const char *, lldb::BasicType> type_suffixes[] = {
333-
{"ull", lldb::eBasicTypeUnsignedLongLong},
334-
{"ul", lldb::eBasicTypeUnsignedLong},
335-
{"u", lldb::eBasicTypeUnsignedInt},
336-
{"ll", lldb::eBasicTypeLongLong},
337-
{"l", lldb::eBasicTypeLong},
338-
};
339-
340-
ASTNodeUP DILParser::ParseNumericConstant() {
341-
Token token = CurToken();
342-
auto spelling = token.GetSpelling();
323+
std::optional<llvm::APInt> DILParser::ParseIntegerConstant() {
324+
auto spelling = CurToken().GetSpelling();
343325
llvm::StringRef spelling_ref = spelling;
344-
lldb::BasicType type = lldb::eBasicTypeInt;
345-
for (auto [suffix, t] : type_suffixes) {
346-
if (spelling_ref.consume_back_insensitive(suffix)) {
347-
type = t;
348-
break;
349-
}
350-
}
351326
llvm::APInt raw_value;
352327
if (!spelling_ref.getAsInteger(0, raw_value)) {
353-
Scalar scalar_value(raw_value);
354-
return std::make_unique<ScalarLiteralNode>(token.GetLocation(), type,
355-
scalar_value);
328+
m_dil_lexer.Advance();
329+
return raw_value;
356330
}
357-
return std::make_unique<ErrorNode>();
331+
332+
return std::nullopt;
358333
}
359334

360335
void DILParser::Expect(Token::Kind kind) {

lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,26 @@ def test_dereference(self):
3030
# Test int[] and int*
3131
self.expect_var_path("int_arr[0]", True, value="1")
3232
self.expect_var_path("int_ptr[1]", True, value="2")
33-
self.expect_var_path("int_arr[enum_one]", value="2")
33+
self.expect("frame var 'int_arr[enum_one]'", error=True)
3434

3535
# Test when base and index are references.
3636
self.expect_var_path("int_arr[0]", True, value="1")
37-
self.expect_var_path("int_arr[idx_1_ref]", value="2")
38-
self.expect_var_path("int_arr[enum_ref]", value="2")
37+
self.expect("frame var 'int_arr[idx_1_ref]'", error=True)
38+
self.expect("frame var 'int_arr[enum_ref]'", error=True)
3939
self.expect_var_path("int_arr_ref[0]", value="1")
40-
self.expect_var_path("int_arr_ref[idx_1_ref]", value="2")
41-
self.expect_var_path("int_arr_ref[enum_ref]", value="2")
40+
self.expect("frame var 'int_arr_ref[idx_1_ref]'", error=True)
41+
self.expect("frame var 'int_arr_ref[enum_ref]'", error=True)
4242

4343
# Test when base and index are typedefs.
4444
self.expect_var_path("td_int_arr[0]", True, value="1")
45-
self.expect_var_path("td_int_arr[td_int_idx_1]", value="2")
46-
self.expect_var_path("td_int_arr[td_td_int_idx_2]", value="3")
45+
self.expect("frame var 'td_int_arr[td_int_idx_1]'", error=True)
46+
self.expect("frame var 'td_int_arr[td_td_int_idx_2]'", error=True)
4747
self.expect_var_path("td_int_ptr[0]", True, value="1")
48-
self.expect_var_path("td_int_ptr[td_int_idx_1]", value="2")
49-
self.expect_var_path("td_int_ptr[td_td_int_idx_2]", value="3")
48+
self.expect("frame var 'td_int_ptr[td_int_idx_1]'", error=True)
49+
self.expect("frame var 'td_int_ptr[td_td_int_idx_2]'", error=True)
5050

5151
# Both typedefs and refs
52-
self.expect_var_path("td_int_arr_ref[td_int_idx_1_ref]", value="2")
52+
self.expect("frame var 'td_int_arr_ref[td_int_idx_1_ref]'", error=True)
5353

5454
# Test for index out of bounds.
5555
self.expect_var_path("int_arr[42]", True, type="int")
@@ -79,10 +79,10 @@ def test_dereference(self):
7979
self.expect(
8080
"frame var 'int_arr[int_ptr]'",
8181
error=True,
82-
substrs=["array subscript is not an integer"],
82+
substrs=["failed to parse integer constant"],
8383
)
8484
self.expect(
8585
"frame var '1[2]'",
8686
error=True,
87-
substrs=["subscripted value is not an array or pointer"],
87+
substrs=["Unexpected token"],
8888
)

0 commit comments

Comments
 (0)