Skip to content

Commit 336d59f

Browse files
committed
Remove array conversion, cut down evaluation of & and *.
1 parent d7fdf3f commit 336d59f

File tree

5 files changed

+32
-136
lines changed

5 files changed

+32
-136
lines changed

lldb/include/lldb/ValueObject/DILAST.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ class ASTNode {
5151

5252
virtual llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const = 0;
5353

54-
virtual bool is_rvalue() const { return false; }
55-
5654
uint32_t GetLocation() const { return m_location; }
5755
NodeKind GetKind() const { return m_kind; }
5856

@@ -97,7 +95,6 @@ class UnaryOpNode : public ASTNode {
9795
m_rhs(std::move(rhs)) {}
9896

9997
llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
100-
bool is_rvalue() const override { return m_kind != UnaryOpKind::Deref; }
10198

10299
UnaryOpKind kind() const { return m_kind; }
103100
ASTNode *rhs() const { return m_rhs.get(); }

lldb/include/lldb/ValueObject/DILEval.h

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,6 @@ lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref,
3838
lldb::DynamicValueType use_dynamic,
3939
CompilerType *scope_ptr = nullptr);
4040

41-
class FlowAnalysis {
42-
public:
43-
FlowAnalysis(bool address_of_is_pending)
44-
: m_address_of_is_pending(address_of_is_pending) {}
45-
46-
bool AddressOfIsPending() const { return m_address_of_is_pending; }
47-
void DiscardAddressOf() { m_address_of_is_pending = false; }
48-
49-
private:
50-
bool m_address_of_is_pending;
51-
};
52-
5341
class Interpreter : Visitor {
5442
public:
5543
Interpreter(lldb::TargetSP target, llvm::StringRef expr,
@@ -59,29 +47,13 @@ class Interpreter : Visitor {
5947
llvm::Expected<lldb::ValueObjectSP> Evaluate(const ASTNode *node);
6048

6149
private:
62-
llvm::Expected<lldb::ValueObjectSP>
63-
EvaluateNode(const ASTNode *node, FlowAnalysis *flow = nullptr);
64-
6550
llvm::Expected<lldb::ValueObjectSP>
6651
Visit(const IdentifierNode *node) override;
6752
llvm::Expected<lldb::ValueObjectSP> Visit(const UnaryOpNode *node) override;
6853

69-
lldb::ValueObjectSP EvaluateDereference(lldb::ValueObjectSP rhs);
70-
71-
FlowAnalysis *flow_analysis() { return m_flow_analysis_chain.back(); }
72-
7354
// Used by the interpreter to create objects, perform casts, etc.
7455
lldb::TargetSP m_target;
7556
llvm::StringRef m_expr;
76-
// Flow analysis chain represents the expression evaluation flow for the
77-
// current code branch. Each node in the chain corresponds to an AST node,
78-
// describing the semantics of the evaluation for it. Currently, flow analysis
79-
// propagates the information about the pending address-of operator, so that
80-
// combination of address-of and a subsequent dereference can be eliminated.
81-
// End of the chain (i.e. `back()`) contains the flow analysis instance for
82-
// the current node. It may be `nullptr` if no relevant information is
83-
// available, the caller/user is supposed to check.
84-
std::vector<FlowAnalysis *> m_flow_analysis_chain;
8557
lldb::ValueObjectSP m_scope;
8658
lldb::DynamicValueType m_default_dynamic;
8759
std::shared_ptr<StackFrame> m_exe_ctx_scope;

lldb/source/ValueObject/DILEval.cpp

Lines changed: 18 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,6 @@
1818

1919
namespace lldb_private::dil {
2020

21-
static lldb::ValueObjectSP
22-
ArrayToPointerConversion(lldb::ValueObjectSP valobj,
23-
std::shared_ptr<ExecutionContextScope> ctx) {
24-
assert(valobj->IsArrayType() &&
25-
"an argument to array-to-pointer conversion must be an array");
26-
27-
uint64_t addr = valobj->GetLoadAddress();
28-
llvm::StringRef name = "result";
29-
ExecutionContext exe_ctx;
30-
ctx->CalculateExecutionContext(exe_ctx);
31-
return ValueObject::CreateValueObjectFromAddress(
32-
name, addr, exe_ctx,
33-
valobj->GetCompilerType().GetArrayElementType(ctx.get()).GetPointerType(),
34-
/* do_deref */ false);
35-
}
36-
3721
static lldb::ValueObjectSP LookupStaticIdentifier(
3822
VariableList &variable_list, std::shared_ptr<StackFrame> exe_scope,
3923
llvm::StringRef name_ref, llvm::StringRef unqualified_name) {
@@ -222,22 +206,9 @@ Interpreter::Interpreter(lldb::TargetSP target, llvm::StringRef expr,
222206
: m_target(std::move(target)), m_expr(expr), m_default_dynamic(use_dynamic),
223207
m_exe_ctx_scope(frame_sp) {}
224208

225-
llvm::Expected<lldb::ValueObjectSP> Interpreter::Evaluate(const ASTNode *tree) {
209+
llvm::Expected<lldb::ValueObjectSP> Interpreter::Evaluate(const ASTNode *node) {
226210
// Evaluate an AST.
227-
auto value_or_error = EvaluateNode(tree);
228-
229-
// Return the computed result-or-error.
230-
return value_or_error;
231-
}
232-
233-
llvm::Expected<lldb::ValueObjectSP>
234-
Interpreter::EvaluateNode(const ASTNode *node, FlowAnalysis *flow) {
235-
// Set up the evaluation context for the current node.
236-
m_flow_analysis_chain.push_back(flow);
237-
// Traverse an AST pointed by the `node`.
238211
auto value_or_error = node->Accept(this);
239-
// Cleanup the context.
240-
m_flow_analysis_chain.pop_back();
241212
// Return the computed value-or-error. The caller is responsible for
242213
// checking if an error occured during the evaluation.
243214
return value_or_error;
@@ -265,33 +236,29 @@ Interpreter::Visit(const IdentifierNode *node) {
265236

266237
llvm::Expected<lldb::ValueObjectSP>
267238
Interpreter::Visit(const UnaryOpNode *node) {
268-
FlowAnalysis rhs_flow(
269-
/* address_of_is_pending */ node->kind() == UnaryOpKind::AddrOf);
270-
271239
Status error;
272-
auto rhs_or_err = EvaluateNode(node->rhs(), &rhs_flow);
240+
auto rhs_or_err = Evaluate(node->rhs());
273241
if (!rhs_or_err) {
274242
return rhs_or_err;
275243
}
276244
lldb::ValueObjectSP rhs = *rhs_or_err;
277245

278-
CompilerType rhs_type = rhs->GetCompilerType();
279246
switch (node->kind()) {
280247
case UnaryOpKind::Deref: {
281-
if (rhs_type.IsArrayType())
282-
rhs = ArrayToPointerConversion(rhs, m_exe_ctx_scope);
283-
284248
lldb::ValueObjectSP dynamic_rhs = rhs->GetDynamicValue(m_default_dynamic);
285249
if (dynamic_rhs)
286250
rhs = dynamic_rhs;
287251

288-
if (rhs->GetCompilerType().IsPointerType()) {
289-
if (rhs->GetCompilerType().IsPointerToVoid()) {
290-
return llvm::make_error<DILDiagnosticError>(
291-
m_expr, "indirection not permitted on operand of type 'void *'",
292-
node->GetLocation(), 1);
293-
}
294-
return EvaluateDereference(rhs);
252+
CompilerType rhs_type = rhs->GetCompilerType();
253+
if (!rhs_type.IsReferenceType() && !rhs_type.IsPointerType())
254+
return llvm::make_error<DILDiagnosticError>(
255+
m_expr, "not a pointer or reference type",
256+
node->rhs()->GetLocation());
257+
258+
if (rhs_type.IsPointerToVoid()) {
259+
return llvm::make_error<DILDiagnosticError>(
260+
m_expr, "indirection not permitted on operand of type 'void *'",
261+
node->GetLocation());
295262
}
296263
lldb::ValueObjectSP child_sp = rhs->Dereference(error);
297264
if (error.Success())
@@ -300,68 +267,19 @@ Interpreter::Visit(const UnaryOpNode *node) {
300267
return rhs;
301268
}
302269
case UnaryOpKind::AddrOf: {
303-
if (node->rhs()->is_rvalue()) {
304-
std::string errMsg =
305-
llvm::formatv("cannot take the address of an rvalue of type {0}",
306-
rhs_type.TypeDescription());
307-
return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
270+
Status error;
271+
lldb::ValueObjectSP value = rhs->AddressOf(error);
272+
if (error.Fail()) {
273+
return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
308274
node->GetLocation());
309275
}
310-
if (rhs->IsBitfield()) {
311-
return llvm::make_error<DILDiagnosticError>(
312-
m_expr, "address of bit-field requested", node->GetLocation());
313-
}
314-
// If the address-of operation wasn't cancelled during the evaluation of
315-
// RHS (e.g. because of the address-of-a-dereference elision), apply it
316-
// here.
317-
if (rhs_flow.AddressOfIsPending()) {
318-
Status error;
319-
lldb::ValueObjectSP value = rhs->AddressOf(error);
320-
if (error.Fail()) {
321-
return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
322-
node->GetLocation());
323-
}
324-
return value;
325-
}
326-
return rhs;
276+
return value;
327277
}
328278
}
329279

330280
// Unsupported/invalid operation.
331281
return llvm::make_error<DILDiagnosticError>(
332-
m_expr, "invalid ast: unexpected binary operator", node->GetLocation(),
333-
1);
334-
}
335-
336-
lldb::ValueObjectSP Interpreter::EvaluateDereference(lldb::ValueObjectSP rhs) {
337-
// If rhs is a reference, dereference it first.
338-
Status error;
339-
if (rhs->GetCompilerType().IsReferenceType())
340-
rhs = rhs->Dereference(error);
341-
342-
assert(rhs->GetCompilerType().IsPointerType() &&
343-
"invalid ast: must be a pointer type");
344-
345-
if (rhs->GetDerefValobj())
346-
return rhs->GetDerefValobj()->GetSP();
347-
348-
CompilerType pointer_type = rhs->GetCompilerType();
349-
lldb::addr_t base_addr = rhs->GetValueAsUnsigned(0);
350-
351-
llvm::StringRef name = "result";
352-
ExecutionContext exe_ctx(m_target.get(), false);
353-
lldb::ValueObjectSP value = ValueObject::CreateValueObjectFromAddress(
354-
name, base_addr, exe_ctx, pointer_type,
355-
/* do_deref */ false);
356-
357-
// If we're in the address-of context, skip the dereference and cancel the
358-
// pending address-of operation as well.
359-
if (flow_analysis() && flow_analysis()->AddressOfIsPending()) {
360-
flow_analysis()->DiscardAddressOf();
361-
return value;
362-
}
363-
364-
return value->Dereference(error);
282+
m_expr, "invalid ast: unexpected binary operator", node->GetLocation());
365283
}
366284

367285
} // namespace lldb_private::dil

lldb/test/API/commands/frame/var-dil/basics/PointerArithmetic/TestFrameVarDILPointerArithmetic.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,25 @@ def test_dereference(self):
2424
lldbutil.run_to_source_breakpoint(
2525
self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
2626
)
27-
is_32bit = self.process().GetAddressByteSize() == 4
2827

2928
self.runCmd("settings set target.experimental.use-DIL true")
3029
self.expect_var_path("*p_int0", True, value="0")
3130
self.expect_var_path("*cp_int5", True, value="5")
3231
self.expect_var_path("*rcp_int0", True, type="const int *")
33-
self.expect_var_path("*array", value="0")
34-
self.expect_var_path(
35-
"&*p_null", value="0x00000000" if is_32bit else "0x0000000000000000"
36-
)
32+
self.expect_var_path("*offset_p", True, value="5")
33+
self.expect_var_path("*offset_pref", True, type="int *")
3734
self.expect_var_path("**pp_int0", value="0")
3835
self.expect_var_path("&**pp_int0", type="int *")
36+
self.expect(
37+
"frame var '*array'",
38+
error=True,
39+
substrs=["not a pointer or reference type"],
40+
)
41+
self.expect(
42+
"frame var '&*p_null'",
43+
error=True,
44+
substrs=["doesn't have a valid address"],
45+
)
3946
self.expect(
4047
"frame var '&*p_void'",
4148
error=True,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ int main(int argc, char **argv) {
66
my_char_ptr my_p_char1 = p_char1;
77

88
int offset = 5;
9+
int *offset_p = &offset;
10+
int *&offset_pref = offset_p;
911
int array[10];
1012
array[0] = 0;
1113
array[offset] = offset;

0 commit comments

Comments
 (0)