[Lldb-commits] [lldb] [LLDB] Add more helper functions to ValueObject class. (PR #87197)

via lldb-commits lldb-commits at lists.llvm.org
Thu Jun 6 12:13:43 PDT 2024


================
@@ -1089,6 +1089,154 @@ int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
   return fail_value;
 }
 
+llvm::Expected<llvm::APSInt> ValueObject::GetValueAsAPSInt() {
+  // Make sure the type can be converted to an APSInt.
+  if (!GetCompilerType().IsInteger() &&
+      !GetCompilerType().IsScopedEnumerationType() &&
+      !GetCompilerType().IsEnumerationType() &&
+      !GetCompilerType().IsPointerType() &&
+      !GetCompilerType().IsNullPtrType() &&
+      !GetCompilerType().IsReferenceType() && !GetCompilerType().IsBoolean())
+    return llvm::make_error<llvm::StringError>(
+        "type cannot be converted to APSInt", llvm::inconvertibleErrorCode());
+
+  if (CanProvideValue()) {
+    Scalar scalar;
+    if (ResolveValue(scalar))
+      return scalar.GetAPSInt();
+  }
+
+  return llvm::make_error<llvm::StringError>(
+      "error occurred; unable to convert to APSInt",
+      llvm::inconvertibleErrorCode());
+}
+
+llvm::Expected<llvm::APFloat> ValueObject::GetValueAsAPFloat() {
+  if (!GetCompilerType().IsFloat())
+    return llvm::make_error<llvm::StringError>(
+        "type cannot be converted to APFloat", llvm::inconvertibleErrorCode());
+
+  if (CanProvideValue()) {
+    Scalar scalar;
+    if (ResolveValue(scalar))
+      return scalar.GetAPFloat();
+  }
+
+  return llvm::make_error<llvm::StringError>(
+      "error occurred; unable to convert to APFloat",
+      llvm::inconvertibleErrorCode());
+}
+
+llvm::Expected<bool> ValueObject::GetValueAsBool() {
+  CompilerType val_type = GetCompilerType();
+  if (val_type.IsInteger() || val_type.IsUnscopedEnumerationType() ||
+      val_type.IsPointerType()) {
+    auto value_or_err = GetValueAsAPSInt();
+    if (value_or_err)
+      return value_or_err->getBoolValue();
+  }
+  if (val_type.IsFloat()) {
+    auto value_or_err = GetValueAsAPFloat();
+    if (value_or_err)
+      return value_or_err->isNonZero();
+  }
+  if (val_type.IsArrayType())
+    return GetAddressOf() != 0;
+
+  return llvm::make_error<llvm::StringError>("type cannot be converted to bool",
+                                             llvm::inconvertibleErrorCode());
+}
+
+void ValueObject::SetValueFromInteger(const llvm::APInt &value, Status &error) {
+  // Verify the current object is an integer object
+  CompilerType val_type = GetCompilerType();
+  if (!val_type.IsInteger() && !val_type.IsUnscopedEnumerationType() &&
+      !val_type.IsFloat() && !val_type.IsPointerType() &&
+      !val_type.IsScalarType()) {
+    error.SetErrorString("current value object is not an integer objet");
+    return;
+  }
+
+  // Verify the current object is not actually associated with any program
+  // variable.
+  if (GetVariable()) {
+    error.SetErrorString("current value object is not a temporary object");
+    return;
+  }
+
+  // Verify the proposed new value is the right size.
+  lldb::TargetSP target = GetTargetSP();
+  uint64_t byte_size = 0;
+  if (auto temp = GetCompilerType().GetByteSize(target.get()))
+    byte_size = temp.value();
+  if (value.getBitWidth() != byte_size * CHAR_BIT) {
+    error.SetErrorString(
+        "illegal argument: new value should be of the same size");
+    return;
+  }
+
+  lldb::DataExtractorSP data_sp;
+  data_sp->SetData(value.getRawData(), byte_size,
+                   target->GetArchitecture().GetByteOrder());
+  data_sp->SetAddressByteSize(
+      static_cast<uint8_t>(target->GetArchitecture().GetAddressByteSize()));
+  SetData(*data_sp, error);
+}
+
+void ValueObject::SetValueFromInteger(lldb::ValueObjectSP new_val_sp,
+                                      Status &error) {
+  // Verify the current object is an integer object
+  CompilerType val_type = GetCompilerType();
+  if (!val_type.IsInteger() && !val_type.IsUnscopedEnumerationType() &&
+      !val_type.IsFloat() && !val_type.IsPointerType() &&
+      !val_type.IsScalarType()) {
+    error.SetErrorString("current value object is not an integer objet");
+    return;
+  }
+
+  // Verify the current object is not actually associated with any program
+  // variable.
+  if (GetVariable()) {
+    error.SetErrorString("current value object is not a temporary object");
+    return;
+  }
+
+  // Verify the proposed new value is the right type.
+  CompilerType new_val_type = new_val_sp->GetCompilerType();
+  if (!new_val_type.IsInteger() && !new_val_type.IsFloat() &&
+      !new_val_type.IsPointerType()) {
+    error.SetErrorString(
+        "illegal argument: new value should be of the same size");
+    return;
+  }
+
+  if (new_val_type.IsInteger()) {
+    auto value_or_err = new_val_sp->GetValueAsAPSInt();
+    if (value_or_err)
+      SetValueFromInteger(*value_or_err, error);
+    else
+      error.SetErrorString("error getting APSInt from new_val_sp");
+  } else if (new_val_type.IsFloat()) {
+    auto value_or_err = new_val_sp->GetValueAsAPFloat();
+    if (value_or_err)
+      SetValueFromInteger(value_or_err->bitcastToAPInt(), error);
+    else
+      error.SetErrorString("error getting APFloat from new_val_sp");
+  } else if (new_val_type.IsPointerType()) {
+    bool success = true;
+    uint64_t int_val = new_val_sp->GetValueAsUnsigned(0, &success);
+    if (success) {
+      lldb::TargetSP target = GetTargetSP();
+      uint64_t num_bits = 0;
+      if (auto temp = new_val_sp->GetCompilerType().GetBitSize(target.get()))
+        num_bits = temp.value();
+      // SetValueFromInteger(llvm::APInt(64, int_val), error);
----------------
jimingham wrote:

Is this leftover from some experiment?

https://github.com/llvm/llvm-project/pull/87197


More information about the lldb-commits mailing list