================
@@ -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
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to