Skip to content

Commit e88379e

Browse files
committed
Store index as int64_t; refactor code.
1 parent b80eb87 commit e88379e

File tree

7 files changed

+56
-54
lines changed

7 files changed

+56
-54
lines changed

lldb/include/lldb/ValueObject/DILAST.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,22 +112,22 @@ class UnaryOpNode : public ASTNode {
112112

113113
class ArraySubscriptNode : public ASTNode {
114114
public:
115-
ArraySubscriptNode(uint32_t location, ASTNodeUP base, llvm::APInt index)
115+
ArraySubscriptNode(uint32_t location, ASTNodeUP base, int64_t index)
116116
: ASTNode(location, NodeKind::eArraySubscriptNode),
117-
m_base(std::move(base)), m_index(std::move(index)) {}
117+
m_base(std::move(base)), m_index(index) {}
118118

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

121121
ASTNode *GetBase() const { return m_base.get(); }
122-
const llvm::APInt *GetIndex() const { return &m_index; }
122+
int64_t GetIndex() const { return m_index; }
123123

124124
static bool classof(const ASTNode *node) {
125125
return node->GetKind() == NodeKind::eArraySubscriptNode;
126126
}
127127

128128
private:
129129
ASTNodeUP m_base;
130-
llvm::APInt m_index;
130+
int64_t m_index;
131131
};
132132

133133
/// This class contains one Visit method for each specialized type of

lldb/include/lldb/ValueObject/DILParser.h

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

9292
std::string ParseIdExpression();
9393
std::string ParseUnqualifiedId();
94-
std::optional<llvm::APInt> ParseIntegerConstant();
94+
std::optional<int64_t> ParseIntegerConstant();
9595

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

lldb/source/ValueObject/DILEval.cpp

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -275,47 +275,29 @@ Interpreter::Visit(const UnaryOpNode *node) {
275275
llvm::Expected<lldb::ValueObjectSP>
276276
Interpreter::Visit(const ArraySubscriptNode *node) {
277277
auto lhs_or_err = Evaluate(node->GetBase());
278-
if (!lhs_or_err) {
278+
if (!lhs_or_err)
279279
return lhs_or_err;
280-
}
281280
lldb::ValueObjectSP base = *lhs_or_err;
282-
const llvm::APInt *index = node->GetIndex();
283-
284-
Status error;
285-
if (base->GetCompilerType().IsReferenceType()) {
286-
base = base->Dereference(error);
287-
if (error.Fail())
288-
return error.ToError();
289-
}
290281

291282
// Check to see if 'base' has a synthetic value; if so, try using that.
292-
uint64_t child_idx = index->getZExtValue();
293-
if (base->HasSyntheticValue()) {
294-
lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
295-
if (synthetic && synthetic != base) {
296-
uint32_t num_children = synthetic->GetNumChildrenIgnoringErrors();
297-
// Verify that the 'index' is not out-of-range for the declared type.
298-
if (child_idx >= num_children) {
299-
auto message = llvm::formatv(
300-
"array index {0} is not valid for \"({1}) {2}\"", child_idx,
301-
base->GetTypeName().AsCString("<invalid type>"),
302-
base->GetName().AsCString());
303-
return llvm::make_error<DILDiagnosticError>(m_expr, message,
304-
node->GetLocation());
305-
}
306-
307-
if (static_cast<uint32_t>(child_idx) <
308-
synthetic->GetNumChildrenIgnoringErrors()) {
309-
lldb::ValueObjectSP child_valobj_sp =
310-
synthetic->GetChildAtIndex(child_idx);
311-
if (child_valobj_sp) {
312-
return child_valobj_sp;
313-
}
314-
}
283+
uint64_t child_idx = node->GetIndex();
284+
if (lldb::ValueObjectSP synthetic = base->GetSyntheticValue()) {
285+
uint32_t num_children = synthetic->GetNumChildrenIgnoringErrors();
286+
// Verify that the 'index' is not out-of-range for the declared type.
287+
if (child_idx >= num_children) {
288+
std::string message = llvm::formatv(
289+
"array index {0} is not valid for \"({1}) {2}\"", child_idx,
290+
base->GetTypeName().AsCString("<invalid type>"),
291+
base->GetName().AsCString());
292+
return llvm::make_error<DILDiagnosticError>(m_expr, message,
293+
node->GetLocation());
315294
}
295+
if (lldb::ValueObjectSP child_valobj_sp =
296+
synthetic->GetChildAtIndex(child_idx))
297+
return child_valobj_sp;
316298
}
317299

318-
auto base_type = base->GetCompilerType();
300+
auto base_type = base->GetCompilerType().GetNonReferenceType();
319301
if (!base_type.IsPointerType() && !base_type.IsArrayType())
320302
return llvm::make_error<DILDiagnosticError>(
321303
m_expr, "subscripted value is not an array or pointer",
@@ -326,12 +308,11 @@ Interpreter::Visit(const ArraySubscriptNode *node) {
326308
node->GetLocation());
327309

328310
if (base_type.IsArrayType()) {
329-
uint32_t num_children = base->GetNumChildrenIgnoringErrors();
330-
if (child_idx < num_children)
331-
return base->GetChildAtIndex(child_idx);
311+
if (lldb::ValueObjectSP child_valobj_sp = base->GetChildAtIndex(child_idx))
312+
return child_valobj_sp;
332313
}
333314

334-
int64_t signed_child_idx = index->getSExtValue();
315+
int64_t signed_child_idx = node->GetIndex();
335316
return base->GetSyntheticArrayMember(signed_child_idx, true);
336317
}
337318

lldb/source/ValueObject/DILLexer.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,8 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
101101

102102
uint32_t position = cur_pos - expr.begin();
103103
std::optional<llvm::StringRef> maybe_number = IsNumber(expr, remainder);
104-
if (maybe_number) {
105-
std::string number = (*maybe_number).str();
106-
return Token(Token::numeric_constant, number, position);
107-
}
104+
if (maybe_number)
105+
return Token(Token::numeric_constant, maybe_number->str(), position);
108106
std::optional<llvm::StringRef> maybe_word = IsWord(expr, remainder);
109107
if (maybe_word)
110108
return Token(Token::identifier, maybe_word->str(), position);

lldb/source/ValueObject/DILParser.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ ASTNodeUP DILParser::ParsePostfixExpression() {
128128
switch (token.GetKind()) {
129129
case Token::l_square: {
130130
m_dil_lexer.Advance();
131-
auto rhs = ParseIntegerConstant();
131+
std::optional<int64_t> rhs = ParseIntegerConstant();
132132
if (!rhs) {
133133
BailOut(
134134
llvm::formatv("failed to parse integer constant: {0}", CurToken()),
@@ -320,11 +320,11 @@ void DILParser::BailOut(const std::string &error, uint32_t loc,
320320
// integer_literal:
321321
// ? Integer constant ?
322322
//
323-
std::optional<llvm::APInt> DILParser::ParseIntegerConstant() {
323+
std::optional<int64_t> DILParser::ParseIntegerConstant() {
324324
auto spelling = CurToken().GetSpelling();
325325
llvm::StringRef spelling_ref = spelling;
326-
llvm::APInt raw_value;
327-
if (!spelling_ref.getAsInteger(0, raw_value)) {
326+
int64_t raw_value;
327+
if (!spelling_ref.getAsInteger<int64_t>(0, raw_value)) {
328328
m_dil_lexer.Advance();
329329
return raw_value;
330330
}

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

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,21 @@ def test_dereference(self):
5858
# Test address-of of the subscripted value.
5959
self.expect_var_path("*(&int_arr[1])", value="2")
6060

61-
# Test synthetic value subscription
62-
self.expect_var_path("vector[1]", value="2")
63-
6461
# Test for negative index.
6562
self.expect(
6663
"frame var 'int_arr[-1]'",
6764
error=True,
6865
substrs=["unrecognized token"],
6966
)
7067

68+
# Test synthetic value subscription
69+
self.expect_var_path("vector[1]", value="2")
70+
self.expect(
71+
"frame var 'vector[100]'",
72+
error=True,
73+
substrs=["array index 100 is not valid"],
74+
)
75+
7176
# Test for floating point index
7277
self.expect(
7378
"frame var 'int_arr[1.0]'",
@@ -76,6 +81,16 @@ def test_dereference(self):
7681
)
7782

7883
# Base should be a "pointer to T" and index should be of an integral type.
84+
self.expect(
85+
"frame var 'idx_1[0]'",
86+
error=True,
87+
substrs=["subscripted value is not an array or pointer"],
88+
)
89+
self.expect(
90+
"frame var 'idx_1_ref[0]'",
91+
error=True,
92+
substrs=["subscripted value is not an array or pointer"],
93+
)
7994
self.expect(
8095
"frame var 'int_arr[int_ptr]'",
8196
error=True,
@@ -86,3 +101,10 @@ def test_dereference(self):
86101
error=True,
87102
substrs=["Unexpected token"],
88103
)
104+
105+
# Base should not be a pointer to void
106+
self.expect(
107+
"frame var 'p_void[0]'",
108+
error=True,
109+
substrs=["subscript of pointer to incomplete type 'void'"],
110+
)

lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ int main(int argc, char **argv) {
44
int int_arr[] = {1, 2, 3};
55
int *int_ptr = int_arr;
66
int(&int_arr_ref)[3] = int_arr;
7+
void *p_void = (void *)int_arr;
78

89
int idx_1 = 1;
910
const int &idx_1_ref = idx_1;

0 commit comments

Comments
 (0)