================
@@ -1089,6 +1089,116 @@ int64_t ValueObject::GetValueAsSigned(int64_t 
fail_value, bool *success) {
   return fail_value;
 }
 
+llvm::APSInt ValueObject::GetValueAsAPSInt() {
+  lldb::TargetSP target = GetTargetSP();
+  uint64_t byte_size = 0;
+  if (auto temp = GetCompilerType().GetByteSize(target.get()))
+    byte_size = temp.value();
+
+  unsigned bit_width = static_cast<unsigned>(byte_size * CHAR_BIT);
+  bool success = true;
+  uint64_t fail_value = 0;
+  uint64_t ret_val = GetValueAsUnsigned(fail_value, &success);
+  uint64_t new_value = fail_value;
+  if (success)
+    new_value = ret_val;
+  bool is_signed = GetCompilerType().IsSigned();
+
+  return llvm::APSInt(llvm::APInt(bit_width, new_value, is_signed), 
!is_signed);
+}
+
+llvm::APFloat ValueObject::GetValueAsFloat() {
+  lldb::BasicType basic_type =
+      GetCompilerType().GetCanonicalType().GetBasicTypeEnumeration();
+  lldb::DataExtractorSP data_sp(new DataExtractor());
+  Status error;
+
+  switch (basic_type) {
+  case lldb::eBasicTypeFloat: {
+    float v = 0;
+    GetData(*data_sp, error);
+    assert(error.Success() && "Unable to read float data from value");
+
+    lldb::offset_t offset = 0;
+    uint32_t old_offset = offset;
+    void *ok = nullptr;
+    ok = data_sp->GetU8(&offset, (void *)&v, sizeof(float));
+    assert(offset != old_offset && ok != nullptr && "unable to read data");
+
+    return llvm::APFloat(v);
+  }
+  case lldb::eBasicTypeDouble:
+    // No way to get more precision at the moment.
+  case lldb::eBasicTypeLongDouble: {
+    double v = 0;
+    GetData(*data_sp, error);
+    assert(error.Success() && "Unable to read long double data from value");
+
+    lldb::offset_t offset = 0;
+    uint32_t old_offset = offset;
+    void *ok = nullptr;
+    ok = data_sp->GetU8(&offset, (void *)&v, sizeof(double));
+    assert(offset != old_offset && ok != nullptr && "unable to read data");
+
+    return llvm::APFloat(v);
+  }
+  default:
+    return llvm::APFloat(NAN);
+  }
+}
+
+bool ValueObject::GetValueAsBool() {
+  CompilerType val_type = GetCompilerType();
+  if (val_type.IsInteger() || val_type.IsUnscopedEnumerationType() ||
+      val_type.IsPointerType()) {
+    return GetValueAsAPSInt().getBoolValue();
+  }
+  if (val_type.IsFloat()) {
+    return GetValueAsFloat().isNonZero();
+  }
+  if (val_type.IsArrayType()) {
+    lldb::ValueObjectSP new_val =
+        ValueObject::ValueObject::CreateValueObjectFromAddress(
+            GetName().GetStringRef(), GetAddressOf(), GetExecutionContextRef(),
+            val_type);
+    return new_val->GetValueAsUnsigned(0) != 0;
+  }
+  return false;
+}
+
+void ValueObject::UpdateIntegerValue(const llvm::APInt &value) {
+  lldb::TargetSP target = GetTargetSP();
+  uint64_t byte_size = 0;
+  if (auto temp = GetCompilerType().GetByteSize(target.get()))
+    byte_size = temp.value();
+
+  assert(value.getBitWidth() == byte_size * CHAR_BIT &&
+         "illegal argument: new value should be of the same size");
+
+  lldb::DataExtractorSP data_sp;
+  Status error;
+  data_sp->SetData(value.getRawData(), byte_size,
+                   target->GetArchitecture().GetByteOrder());
----------------
clayborg wrote:

This will crash, `data_sp` is never constructed or assigned. We also need to 
figure out if we are going to want the integer value to be replaced always with 
a local copy, or updated in the actual program memory, register, or local 
buffer.

I realize many of these APIs are probably only intended to be used in the new 
ValueObject based expression parser, but there are APIs being added to 
ValueObject so they should work regardless of where they come from or originate.

https://github.com/llvm/llvm-project/pull/87197
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to