[Lldb-commits] [lldb] [LLDB] Add unary operators Dereference and AddressOf to DIL (PR #134428)
Ilia Kuklin via lldb-commits
lldb-commits at lists.llvm.org
Wed Apr 9 15:48:36 PDT 2025
================
@@ -232,4 +263,105 @@ Interpreter::Visit(const IdentifierNode *node) {
return identifier;
}
-} // namespace lldb_private::dil
+llvm::Expected<lldb::ValueObjectSP>
+Interpreter::Visit(const UnaryOpNode *node) {
+ FlowAnalysis rhs_flow(
+ /* address_of_is_pending */ node->kind() == UnaryOpKind::AddrOf);
+
+ Status error;
+ auto rhs_or_err = EvaluateNode(node->rhs(), &rhs_flow);
+ if (!rhs_or_err) {
+ return rhs_or_err;
+ }
+ lldb::ValueObjectSP rhs = *rhs_or_err;
+
+ CompilerType rhs_type = rhs->GetCompilerType();
+ switch (node->kind()) {
+ case UnaryOpKind::Deref: {
+ if (rhs_type.IsArrayType())
+ rhs = ArrayToPointerConversion(rhs, m_exe_ctx_scope);
+
+ lldb::ValueObjectSP dynamic_rhs = rhs->GetDynamicValue(m_default_dynamic);
+ if (dynamic_rhs)
+ rhs = dynamic_rhs;
+
+ if (rhs->GetCompilerType().IsPointerType()) {
+ if (rhs->GetCompilerType().IsPointerToVoid()) {
+ return llvm::make_error<DILDiagnosticError>(
+ m_expr, "indirection not permitted on operand of type 'void *'",
+ node->GetLocation(), 1);
+ }
+ return EvaluateDereference(rhs);
+ }
+ lldb::ValueObjectSP child_sp = rhs->Dereference(error);
+ if (error.Success())
+ rhs = child_sp;
+
+ return rhs;
+ }
+ case UnaryOpKind::AddrOf: {
+ if (node->rhs()->is_rvalue()) {
+ std::string errMsg =
+ llvm::formatv("cannot take the address of an rvalue of type {0}",
+ rhs_type.TypeDescription());
+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
+ node->GetLocation());
+ }
+ if (rhs->IsBitfield()) {
+ return llvm::make_error<DILDiagnosticError>(
+ m_expr, "address of bit-field requested", node->GetLocation());
+ }
+ // If the address-of operation wasn't cancelled during the evaluation of
+ // RHS (e.g. because of the address-of-a-dereference elision), apply it
+ // here.
+ if (rhs_flow.AddressOfIsPending()) {
+ Status error;
+ lldb::ValueObjectSP value = rhs->AddressOf(error);
+ if (error.Fail()) {
+ return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
+ node->GetLocation());
+ }
+ return value;
+ }
+ return rhs;
+ }
+ }
+
+ // Unsupported/invalid operation.
+ return llvm::make_error<DILDiagnosticError>(
+ m_expr, "invalid ast: unexpected binary operator", node->GetLocation(),
+ 1);
+}
+
+lldb::ValueObjectSP Interpreter::EvaluateDereference(lldb::ValueObjectSP rhs) {
+ // If rhs is a reference, dereference it first.
+ Status error;
+ if (rhs->GetCompilerType().IsReferenceType())
+ rhs = rhs->Dereference(error);
+
+ assert(rhs->GetCompilerType().IsPointerType() &&
+ "invalid ast: must be a pointer type");
+
+ if (rhs->GetDerefValobj())
----------------
kuilpd wrote:
This checks if the value has already been dereferenced. The same check is also done in the beginning of `Dereference()`, but if we want to skip `CreateValueObjectFromAddress` as well, this is done separately beforehand.
https://github.com/llvm/llvm-project/pull/134428
More information about the lldb-commits
mailing list