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

>From 68cb68d3f93aed6b3479fb305131b99ec599c9d8 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmt...@google.com>
Date: Sun, 31 Mar 2024 10:59:38 -0700
Subject: [PATCH 1/2] [LLDB] Add more helper functions to ValueObject class.

Create additional helper functions for the ValueObject class, for:
  - returning the value as an APSInt or APFloat
  - additional type casting options
  - additional ways to create ValueObjects from various types of data
  - dereferencing a ValueObject

These helper functions are needed for implementing the Data Inspection
Language, described in
https://discourse.llvm.org/t/rfc-data-inspection-language/69893
---
 lldb/include/lldb/Core/ValueObject.h |  61 ++++
 lldb/source/Core/ValueObject.cpp     | 405 +++++++++++++++++++++++++++
 2 files changed, 466 insertions(+)

diff --git a/lldb/include/lldb/Core/ValueObject.h 
b/lldb/include/lldb/Core/ValueObject.h
index e7e35e2b2bffc0..0c8dbf384a326c 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -441,6 +441,19 @@ class ValueObject {
 
   virtual int64_t GetValueAsSigned(int64_t fail_value, bool *success = 
nullptr);
 
+  llvm::APSInt GetValueAsAPSInt();
+
+  llvm::APFloat GetValueAsFloat();
+
+  bool GetValueAsBool();
+
+  /// Update the value of the current object to be the integer in the 'value'
+  /// parameter.
+  void UpdateIntegerValue(const llvm::APInt &value);
+
+  /// Assign the integer value 'new_val_sp' to the current object.
+  void UpdateIntegerValue(lldb::ValueObjectSP new_val_sp);
+
   virtual bool SetValueFromCString(const char *value_str, Status &error);
 
   /// Return the module associated with this value object in case the value is
@@ -618,6 +631,24 @@ class ValueObject {
   virtual lldb::ValueObjectSP CastPointerType(const char *name,
                                               lldb::TypeSP &type_sp);
 
+  /// Return the target load address assocaited with this value object.
+  lldb::addr_t GetLoadAddress();
+
+  lldb::ValueObjectSP CastDerivedToBaseType(CompilerType type,
+                                            const std::vector<uint32_t> &idx);
+
+  lldb::ValueObjectSP CastBaseToDerivedType(CompilerType type, uint64_t 
offset);
+
+  lldb::ValueObjectSP CastScalarToBasicType(CompilerType type, Status &error);
+
+  lldb::ValueObjectSP CastEnumToBasicType(CompilerType type);
+
+  lldb::ValueObjectSP CastPointerToBasicType(CompilerType type);
+
+  lldb::ValueObjectSP CastIntegerOrEnumToEnumType(CompilerType type);
+
+  lldb::ValueObjectSP CastFloatToEnumType(CompilerType type, Status &error);
+
   /// If this object represents a C++ class with a vtable, return an object
   /// that represents the virtual function table. If the object isn't a class
   /// with a vtable, return a valid ValueObject with the error set correctly.
@@ -668,6 +699,32 @@ class ValueObject {
   CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data,
                             const ExecutionContext &exe_ctx, CompilerType 
type);
 
+  static lldb::ValueObjectSP
+  CreateValueObjectFromBytes(lldb::TargetSP target_sp, const void *bytes,
+                             CompilerType type);
+
+  static lldb::ValueObjectSP CreateValueObjectFromBytes(lldb::TargetSP target,
+                                                        const void *bytes,
+                                                        lldb::BasicType type);
+
+  static lldb::ValueObjectSP CreateValueObjectFromAPInt(lldb::TargetSP target,
+                                                        const llvm::APInt &v,
+                                                        CompilerType type);
+
+  static lldb::ValueObjectSP
+  CreateValueObjectFromAPFloat(lldb::TargetSP target, const llvm::APFloat &v,
+                               CompilerType type);
+
+  static lldb::ValueObjectSP CreateValueObjectFromPointer(lldb::TargetSP 
target,
+                                                          uintptr_t addr,
+                                                          CompilerType type);
+
+  static lldb::ValueObjectSP CreateValueObjectFromBool(lldb::TargetSP target,
+                                                       bool value);
+
+  static lldb::ValueObjectSP CreateValueObjectFromNullptr(lldb::TargetSP 
target,
+                                                          CompilerType type);
+
   lldb::ValueObjectSP Persist();
 
   /// Returns true if this is a char* or a char[] if it is a char* and
@@ -719,6 +776,10 @@ class ValueObject {
     ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
   }
 
+  void SetDerefValobj(ValueObject *deref) { m_deref_valobj = deref; }
+
+  ValueObject *GetDerefValobj() { return m_deref_valobj; }
+
   void SetValueFormat(lldb::TypeFormatImplSP format) {
     m_type_format_sp = std::move(format);
     ClearUserVisibleData(eClearUserVisibleDataItemsValue);
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index f39bd07a255366..70cd3bdece8a40 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -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());
+  data_sp->SetAddressByteSize(
+      static_cast<uint8_t>(target->GetArchitecture().GetAddressByteSize()));
+  SetData(*data_sp, error);
+}
+
+void ValueObject::UpdateIntegerValue(lldb::ValueObjectSP new_val_sp) {
+  CompilerType new_val_type = new_val_sp->GetCompilerType();
+  assert((new_val_type.IsInteger() || new_val_type.IsFloat() ||
+          new_val_type.IsPointerType()) &&
+         "illegal argument: new value should be of the same size");
+
+  if (new_val_type.IsInteger()) {
+    UpdateIntegerValue(new_val_sp->GetValueAsAPSInt());
+  } else if (new_val_type.IsFloat()) {
+    UpdateIntegerValue(new_val_sp->GetValueAsFloat().bitcastToAPInt());
+  } else if (new_val_type.IsPointerType()) {
+    UpdateIntegerValue(llvm::APInt(64, new_val_sp->GetValueAsUnsigned(0)));
+  }
+}
+
 // if any more "special cases" are added to
 // ValueObject::DumpPrintableRepresentation() please keep this call up to date
 // by returning true for your new special cases. We will eventually move to
@@ -2809,6 +2919,243 @@ ValueObjectSP ValueObject::CastPointerType(const char 
*name, TypeSP &type_sp) {
   return valobj_sp;
 }
 
+lldb::addr_t ValueObject::GetLoadAddress() {
+  lldb::addr_t addr_value = LLDB_INVALID_ADDRESS;
+  lldb::TargetSP target_sp = GetTargetSP();
+  if (target_sp) {
+    const bool scalar_is_load_address = true;
+    AddressType addr_type;
+    addr_value = GetAddressOf(scalar_is_load_address, &addr_type);
+    if (addr_type == eAddressTypeFile) {
+      lldb::ModuleSP module_sp(GetModule());
+      if (!module_sp)
+        addr_value = LLDB_INVALID_ADDRESS;
+      else {
+        Address tmp_addr;
+        module_sp->ResolveFileAddress(addr_value, tmp_addr);
+        addr_value = tmp_addr.GetLoadAddress(target_sp.get());
+      }
+    } else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeHost)
+      addr_value = LLDB_INVALID_ADDRESS;
+  }
+  return addr_value;
+}
+
+lldb::ValueObjectSP
+ValueObject::CastDerivedToBaseType(CompilerType type,
+                                   const std::vector<uint32_t> &idx) {
+
+  lldb::TargetSP target = GetTargetSP();
+  assert((type.IsPointerType() || type.IsReferenceType()) &&
+         "invalid ast: target type should be a pointer or a reference");
+  assert(!idx.empty() && "invalid ast: children sequence should be non-empty");
+
+  // The `value` can be a pointer, but GetChildAtIndex works for pointers too.
+  lldb::ValueObjectSP inner_value;
+
+  for (const uint32_t i : idx) {
+    // Force static value, otherwise we can end up with the "real" type.
+    inner_value = GetChildAtIndex(i, /*can_create_synthetic*/ false);
+  }
+
+  // At this point type of `inner_value` should be the dereferenced target 
type.
+  CompilerType inner_value_type = inner_value->GetCompilerType();
+  if (type.IsPointerType()) {
+    assert(inner_value_type.CompareTypes(type.GetPointeeType()) &&
+           "casted value doesn't match the desired type");
+
+    uintptr_t addr = inner_value->GetLoadAddress();
+    return ValueObject::CreateValueObjectFromPointer(target, addr, type);
+  }
+
+  // At this point the target type should be a reference.
+  assert(inner_value_type.CompareTypes(type.GetNonReferenceType()) &&
+         "casted value doesn't match the desired type");
+
+  return lldb::ValueObjectSP(inner_value->Cast(type.GetNonReferenceType()));
+}
+
+lldb::ValueObjectSP ValueObject::CastBaseToDerivedType(CompilerType type,
+                                                       uint64_t offset) {
+  lldb::TargetSP target = GetTargetSP();
+
+  assert((type.IsPointerType() || type.IsReferenceType()) &&
+         "invalid ast: target type should be a pointer or a reference");
+
+  auto pointer_type =
+      type.IsPointerType() ? type : 
type.GetNonReferenceType().GetPointerType();
+
+  uintptr_t addr =
+      type.IsPointerType() ? GetValueAsUnsigned(0) : GetLoadAddress();
+
+  lldb::ValueObjectSP value = ValueObject::CreateValueObjectFromPointer(
+      target, addr - offset, pointer_type);
+
+  if (type.IsPointerType()) {
+    return value;
+  }
+
+  // At this point the target type is a reference. Since `value` is a pointer,
+  // it has to be dereferenced.
+  Status error;
+  return value->Dereference(error);
+}
+
+lldb::ValueObjectSP ValueObject::CastScalarToBasicType(CompilerType type,
+                                                       Status &error) {
+  assert(type.IsScalarType() && "target type must be an scalar");
+  assert(GetCompilerType().IsScalarType() && "argument must be a scalar");
+
+  lldb::TargetSP target = GetTargetSP();
+  if (type.IsBoolean()) {
+    if (GetCompilerType().IsInteger()) {
+      return ValueObject::CreateValueObjectFromBool(target,
+                                                    GetValueAsUnsigned(0) != 
0);
+    }
+    if (GetCompilerType().IsFloat()) {
+      return ValueObject::CreateValueObjectFromBool(
+          target, !GetValueAsFloat().isZero());
+    }
+  }
+  if (type.IsInteger()) {
+    if (GetCompilerType().IsInteger()) {
+      uint64_t byte_size = 0;
+      if (auto temp = type.GetByteSize(target.get()))
+        byte_size = temp.value();
+      llvm::APSInt ext = GetValueAsAPSInt().extOrTrunc(byte_size * CHAR_BIT);
+      return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+    }
+    if (GetCompilerType().IsFloat()) {
+      uint64_t byte_size = 0;
+      if (auto temp = type.GetByteSize(target.get()))
+        byte_size = temp.value();
+      llvm::APSInt integer(byte_size * CHAR_BIT, !type.IsSigned());
+      bool is_exact;
+      llvm::APFloatBase::opStatus status = GetValueAsFloat().convertToInteger(
+          integer, llvm::APFloat::rmTowardZero, &is_exact);
+
+      // Casting floating point values that are out of bounds of the target 
type
+      // is undefined behaviour.
+      if (status & llvm::APFloatBase::opInvalidOp) {
+        error.SetErrorString("invalid type cast detected");
+      }
+
+      return ValueObject::CreateValueObjectFromAPInt(target, integer, type);
+    }
+  }
+  if (type.IsFloat()) {
+    if (GetCompilerType().IsInteger()) {
+      Scalar scalar_int(GetValueAsAPSInt());
+      llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
+          type.GetCanonicalType().GetBasicTypeEnumeration());
+      return ValueObject::CreateValueObjectFromAPFloat(target, f, type);
+    }
+    if (GetCompilerType().IsFloat()) {
+      Scalar scalar_float(GetValueAsFloat());
+      llvm::APFloat f = scalar_float.CreateAPFloatFromAPFloat(
+          type.GetCanonicalType().GetBasicTypeEnumeration());
+      return ValueObject::CreateValueObjectFromAPFloat(target, f, type);
+    }
+  }
+  assert(false && "invalid target type: must be a scalar");
+  return lldb::ValueObjectSP();
+}
+
+lldb::ValueObjectSP ValueObject::CastEnumToBasicType(CompilerType type) {
+  lldb::TargetSP target = GetTargetSP();
+
+  assert(type.IsScalarType() && "target type must be a scalar");
+  assert(GetCompilerType().IsEnumerationType() && "argument must be an enum");
+
+  if (type.IsBoolean()) {
+    return ValueObject::CreateValueObjectFromBool(target,
+                                                  GetValueAsUnsigned(0) != 0);
+  }
+
+  uint64_t byte_size = 0;
+  if (auto temp = type.GetByteSize(target.get()))
+    byte_size = temp.value();
+  // Get the value as APSInt and extend or truncate it to the requested size.
+  llvm::APSInt ext = GetValueAsAPSInt().extOrTrunc(byte_size * CHAR_BIT);
+
+  if (type.IsInteger()) {
+    return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+  }
+  if (type.IsFloat()) {
+    Scalar scalar_int(ext);
+    llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
+        type.GetCanonicalType().GetBasicTypeEnumeration());
+    return ValueObject::CreateValueObjectFromAPFloat(target, f, type);
+  }
+  assert(false && "invalid target type: must be a scalar");
+  return lldb::ValueObjectSP();
+}
+
+lldb::ValueObjectSP ValueObject::CastPointerToBasicType(CompilerType type) {
+  lldb::TargetSP target = GetTargetSP();
+
+  uint64_t type_byte_size = 0;
+  uint64_t val_byte_size = 0;
+  if (auto temp = type.GetByteSize(target.get()))
+    type_byte_size = temp.value();
+  if (auto temp = GetCompilerType().GetByteSize(target.get()))
+    val_byte_size = temp.value();
+  assert(type.IsInteger() && "target type must be an integer");
+  assert((type.IsBoolean() || type_byte_size >= val_byte_size) &&
+         "target type cannot be smaller than the pointer type");
+
+  if (type.IsBoolean()) {
+    return ValueObject::CreateValueObjectFromBool(target,
+                                                  GetValueAsUnsigned(0) != 0);
+  }
+
+  // Get the value as APSInt and extend or truncate it to the requested size.
+  llvm::APSInt ext = GetValueAsAPSInt().extOrTrunc(type_byte_size * CHAR_BIT);
+  return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+}
+
+lldb::ValueObjectSP
+ValueObject::CastIntegerOrEnumToEnumType(CompilerType type) {
+  lldb::TargetSP target = GetTargetSP();
+
+  assert(type.IsEnumerationType() && "target type must be an enum");
+  assert((GetCompilerType().IsInteger() ||
+          GetCompilerType().IsEnumerationType()) &&
+         "argument must be an integer or an enum");
+  uint64_t byte_size = 0;
+  if (auto temp = type.GetByteSize(target.get()))
+    byte_size = temp.value();
+
+  // Get the value as APSInt and extend or truncate it to the requested size.
+  llvm::APSInt ext = GetValueAsAPSInt().extOrTrunc(byte_size * CHAR_BIT);
+  return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+}
+
+lldb::ValueObjectSP ValueObject::CastFloatToEnumType(CompilerType type,
+                                                     Status &error) {
+  lldb::TargetSP target = GetTargetSP();
+
+  assert(type.IsEnumerationType() && "target type must be an enum");
+  assert(GetCompilerType().IsFloat() && "argument must be a float");
+
+  uint64_t byte_size = 0;
+  if (auto temp = type.GetByteSize(target.get()))
+    byte_size = temp.value();
+  llvm::APSInt integer(byte_size * CHAR_BIT, !type.IsSigned());
+  bool is_exact;
+
+  llvm::APFloatBase::opStatus status = GetValueAsFloat().convertToInteger(
+      integer, llvm::APFloat::rmTowardZero, &is_exact);
+
+  // Casting floating point values that are out of bounds of the target type
+  // is undefined behaviour.
+  if (status & llvm::APFloatBase::opInvalidOp) {
+    error.SetErrorString("invalid type cast detected");
+  }
+
+  return ValueObject::CreateValueObjectFromAPInt(target, integer, type);
+}
+
 ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() 
{}
 
 ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,
@@ -3031,6 +3378,64 @@ lldb::ValueObjectSP 
ValueObject::CreateValueObjectFromData(
   return new_value_sp;
 }
 
+lldb::ValueObjectSP
+ValueObject::CreateValueObjectFromBytes(lldb::TargetSP target_sp,
+                                        const void *bytes, CompilerType type) {
+  ExecutionContext exe_ctx(
+      ExecutionContextRef(ExecutionContext(target_sp.get(), false)));
+  uint64_t byte_size = 0;
+  if (auto temp = type.GetByteSize(target_sp.get()))
+    byte_size = temp.value();
+  lldb::DataExtractorSP data_sp = std::make_shared<DataExtractor>(
+      bytes, byte_size, target_sp->GetArchitecture().GetByteOrder(),
+      static_cast<uint8_t>(target_sp->GetArchitecture().GetAddressByteSize()));
+  lldb::ValueObjectSP value =
+      ValueObject::CreateValueObjectFromData("result", *data_sp, exe_ctx, 
type);
+  return value;
+}
+
+lldb::ValueObjectSP ValueObject::CreateValueObjectFromBytes(
+    lldb::TargetSP target, const void *bytes, lldb::BasicType type) {
+  CompilerType target_type;
+  if (target) {
+    for (auto type_system_sp : target->GetScratchTypeSystems())
+      if (auto compiler_type = type_system_sp->GetBasicTypeFromAST(type)) {
+        target_type = compiler_type;
+        break;
+      }
+  }
+  return CreateValueObjectFromBytes(target, bytes, target_type);
+}
+
+lldb::ValueObjectSP ValueObject::CreateValueObjectFromAPInt(
+    lldb::TargetSP target, const llvm::APInt &v, CompilerType type) {
+  return CreateValueObjectFromBytes(target, v.getRawData(), type);
+}
+
+lldb::ValueObjectSP ValueObject::CreateValueObjectFromAPFloat(
+    lldb::TargetSP target, const llvm::APFloat &v, CompilerType type) {
+  return CreateValueObjectFromAPInt(target, v.bitcastToAPInt(), type);
+}
+
+lldb::ValueObjectSP
+ValueObject::CreateValueObjectFromPointer(lldb::TargetSP target, uintptr_t 
addr,
+                                          CompilerType type) {
+  return CreateValueObjectFromBytes(target, &addr, type);
+}
+
+lldb::ValueObjectSP
+ValueObject::CreateValueObjectFromBool(lldb::TargetSP target, bool value) {
+  return CreateValueObjectFromBytes(target, &value, lldb::eBasicTypeBool);
+}
+
+lldb::ValueObjectSP
+ValueObject::CreateValueObjectFromNullptr(lldb::TargetSP target,
+                                          CompilerType type) {
+  assert(type.IsNullPtrType() && "target type must be nullptr");
+  uintptr_t zero = 0;
+  return CreateValueObjectFromBytes(target, &zero, type);
+}
+
 ModuleSP ValueObject::GetModule() {
   ValueObject *root(GetRoot());
   if (root != this)

>From 145e74b6d4361b9749e49acc025cda45827c5d96 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmt...@google.com>
Date: Mon, 8 Apr 2024 09:46:32 -0700
Subject: [PATCH 2/2] [LLDB] Add more helper functions to ValueObject class.

Fix various issues in  GetValueAsAPSInt, GetValueAsAPFloat,
GetValueAsBool, UpdateIntegerValue (renamed to SetValueFromInteger),
and GetLoadAddress:

- Added error checking & reporting.
- Removed asserts.
- Added doxygen comments.
- Renamed UpdateIntegerValue to SetValueFromInteger
- Renamed GetValueAsFloat to GetValueAsAPFloat
- Updated code in GetValue... functions to use existing Scalar values
  where possibled.
- Updated SBValue::GetLoadAddress to call ValueObject::GetLoadAddress.
---
 lldb/include/lldb/Core/ValueObject.h |  37 ++--
 lldb/include/lldb/Utility/Scalar.h   |   4 +
 lldb/source/API/SBValue.cpp          |  22 +-
 lldb/source/Core/ValueObject.cpp     | 312 +++++++++++++++++----------
 4 files changed, 223 insertions(+), 152 deletions(-)

diff --git a/lldb/include/lldb/Core/ValueObject.h 
b/lldb/include/lldb/Core/ValueObject.h
index 0c8dbf384a326c..c81f57d2a174f2 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -441,18 +441,29 @@ class ValueObject {
 
   virtual int64_t GetValueAsSigned(int64_t fail_value, bool *success = 
nullptr);
 
-  llvm::APSInt GetValueAsAPSInt();
-
-  llvm::APFloat GetValueAsFloat();
-
-  bool GetValueAsBool();
-
-  /// Update the value of the current object to be the integer in the 'value'
-  /// parameter.
-  void UpdateIntegerValue(const llvm::APInt &value);
-
-  /// Assign the integer value 'new_val_sp' to the current object.
-  void UpdateIntegerValue(lldb::ValueObjectSP new_val_sp);
+  /// If the current ValueObject is of an appropriate type, convert the
+  /// value to an APSInt and return that. Otherwise return an error.
+  llvm::Expected<llvm::APSInt> GetValueAsAPSInt();
+
+  /// If the current ValueObject is of an appropriate type, convert the
+  /// value to an APFloat and return that. Otherwise return an error.
+  llvm::Expected<llvm::APFloat> GetValueAsAPFloat();
+
+  /// If the current ValueObject is of an appropriate type, convert the
+  /// value to a boolean and return that. Otherwise return an error.
+  llvm::Expected<bool> GetValueAsBool();
+
+  /// Update an existing integer ValueObject with a new integer value. This
+  /// is only intended to be used with 'temporary' ValueObjects, i.e. ones that
+  /// are not associated with program variables. It does not update program
+  /// memory, registers, stack, etc.
+  void SetValueFromInteger(const llvm::APInt &value, Status &error);
+
+  /// Update an existing integer ValueObject with an integer value created
+  /// frome 'new_val_sp'.  This is only intended to be used with 'temporary'
+  /// ValueObjects, i.e. ones that are not associated with program variables.
+  /// It does not update program  memory, registers, stack, etc.
+  void SetValueFromInteger(lldb::ValueObjectSP new_val_sp, Status &error);
 
   virtual bool SetValueFromCString(const char *value_str, Status &error);
 
@@ -631,7 +642,7 @@ class ValueObject {
   virtual lldb::ValueObjectSP CastPointerType(const char *name,
                                               lldb::TypeSP &type_sp);
 
-  /// Return the target load address assocaited with this value object.
+  /// Return the target load address associated with this value object.
   lldb::addr_t GetLoadAddress();
 
   lldb::ValueObjectSP CastDerivedToBaseType(CompilerType type,
diff --git a/lldb/include/lldb/Utility/Scalar.h 
b/lldb/include/lldb/Utility/Scalar.h
index d7155884c6d1b8..0d8eba3c9726d5 100644
--- a/lldb/include/lldb/Utility/Scalar.h
+++ b/lldb/include/lldb/Utility/Scalar.h
@@ -181,6 +181,10 @@ class Scalar {
 
   long double LongDouble(long double fail_value = 0.0) const;
 
+  llvm::APSInt GetAPSInt() const { return m_integer; }
+
+  llvm::APFloat GetAPFloat() const { return m_float; }
+
   Status SetValueFromCString(const char *s, lldb::Encoding encoding,
                              size_t byte_size);
 
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 94a8f3ea319e89..9d1c720d9fc701 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -1262,26 +1262,8 @@ lldb::addr_t SBValue::GetLoadAddress() {
   lldb::addr_t value = LLDB_INVALID_ADDRESS;
   ValueLocker locker;
   lldb::ValueObjectSP value_sp(GetSP(locker));
-  if (value_sp) {
-    TargetSP target_sp(value_sp->GetTargetSP());
-    if (target_sp) {
-      const bool scalar_is_load_address = true;
-      AddressType addr_type;
-      value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
-      if (addr_type == eAddressTypeFile) {
-        ModuleSP module_sp(value_sp->GetModule());
-        if (!module_sp)
-          value = LLDB_INVALID_ADDRESS;
-        else {
-          Address addr;
-          module_sp->ResolveFileAddress(value, addr);
-          value = addr.GetLoadAddress(target_sp.get());
-        }
-      } else if (addr_type == eAddressTypeHost ||
-                 addr_type == eAddressTypeInvalid)
-        value = LLDB_INVALID_ADDRESS;
-    }
-  }
+  if (value_sp)
+    return value_sp->GetLoadAddress();
 
   return value;
 }
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 70cd3bdece8a40..2fd7d100712b9b 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -1089,94 +1089,91 @@ 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();
+llvm::Expected<llvm::APSInt> ValueObject::GetValueAsAPSInt() {
+  // Make sure the type can be converted to an APSInt.
+  if (!GetCompilerType().IsInteger() &&
+      !GetCompilerType().IsScopedEnumerationType() &&
+      !GetCompilerType().IsPointerType() &&
+      !GetCompilerType().IsReferenceType() && !GetCompilerType().IsBoolean())
+    return llvm::make_error<llvm::StringError>(
+        "type cannot be converted to APSInt", llvm::inconvertibleErrorCode());
 
-  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();
+  if (CanProvideValue()) {
+    Scalar scalar;
+    if (ResolveValue(scalar))
+      return scalar.GetAPSInt();
+  }
 
-  return llvm::APSInt(llvm::APInt(bit_width, new_value, is_signed), 
!is_signed);
+  return llvm::make_error<llvm::StringError>(
+      "error occurred; unable to convert to APSInt",
+      llvm::inconvertibleErrorCode());
 }
 
-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");
+llvm::Expected<llvm::APFloat> ValueObject::GetValueAsAPFloat() {
+  if (!GetCompilerType().IsFloat())
+    return llvm::make_error<llvm::StringError>(
+        "type cannot be converted to APFloat", llvm::inconvertibleErrorCode());
 
-    return llvm::APFloat(v);
+  if (CanProvideValue()) {
+    Scalar scalar;
+    if (ResolveValue(scalar))
+      return scalar.GetAPFloat();
   }
-  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);
-  }
+  return llvm::make_error<llvm::StringError>(
+      "error occurred; unable to convert to APFloat",
+      llvm::inconvertibleErrorCode());
 }
 
-bool ValueObject::GetValueAsBool() {
+llvm::Expected<bool> ValueObject::GetValueAsBool() {
   CompilerType val_type = GetCompilerType();
   if (val_type.IsInteger() || val_type.IsUnscopedEnumerationType() ||
       val_type.IsPointerType()) {
-    return GetValueAsAPSInt().getBoolValue();
+    auto value_or_err = GetValueAsAPSInt();
+    if (value_or_err)
+      return value_or_err->getBoolValue();
   }
   if (val_type.IsFloat()) {
-    return GetValueAsFloat().isNonZero();
+    auto value_or_err = GetValueAsAPFloat();
+    if (value_or_err)
+      return value_or_err->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 GetAddressOf() != 0;
   }
-  return false;
+  return llvm::make_error<llvm::StringError>("type cannot be converted to 
bool",
+                                             llvm::inconvertibleErrorCode());
 }
 
-void ValueObject::UpdateIntegerValue(const llvm::APInt &value) {
+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();
-
-  assert(value.getBitWidth() == byte_size * CHAR_BIT &&
-         "illegal argument: new value should be of the same size");
+  if (value.getBitWidth() != byte_size * CHAR_BIT) {
+    error.SetErrorString(
+        "illegal argument: new value should be of the same size");
+    return;
+  }
 
   lldb::DataExtractorSP data_sp;
-  Status error;
   data_sp->SetData(value.getRawData(), byte_size,
                    target->GetArchitecture().GetByteOrder());
   data_sp->SetAddressByteSize(
@@ -1184,18 +1181,57 @@ void ValueObject::UpdateIntegerValue(const llvm::APInt 
&value) {
   SetData(*data_sp, error);
 }
 
-void ValueObject::UpdateIntegerValue(lldb::ValueObjectSP new_val_sp) {
+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();
-  assert((new_val_type.IsInteger() || new_val_type.IsFloat() ||
-          new_val_type.IsPointerType()) &&
-         "illegal argument: new value should be of the same size");
+  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()) {
-    UpdateIntegerValue(new_val_sp->GetValueAsAPSInt());
+    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()) {
-    UpdateIntegerValue(new_val_sp->GetValueAsFloat().bitcastToAPInt());
+    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()) {
-    UpdateIntegerValue(llvm::APInt(64, new_val_sp->GetValueAsUnsigned(0)));
+    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);
+      SetValueFromInteger(llvm::APInt(num_bits, int_val), error);
+    } else
+      error.SetErrorString("error converting new_val_sp to integer");
   }
 }
 
@@ -2921,8 +2957,7 @@ ValueObjectSP ValueObject::CastPointerType(const char 
*name, TypeSP &type_sp) {
 
 lldb::addr_t ValueObject::GetLoadAddress() {
   lldb::addr_t addr_value = LLDB_INVALID_ADDRESS;
-  lldb::TargetSP target_sp = GetTargetSP();
-  if (target_sp) {
+  if (auto target_sp = GetTargetSP()) {
     const bool scalar_is_load_address = true;
     AddressType addr_type;
     addr_value = GetAddressOf(scalar_is_load_address, &addr_type);
@@ -2935,7 +2970,8 @@ lldb::addr_t ValueObject::GetLoadAddress() {
         module_sp->ResolveFileAddress(addr_value, tmp_addr);
         addr_value = tmp_addr.GetLoadAddress(target_sp.get());
       }
-    } else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeHost)
+    } else if (addr_type == eAddressTypeHost ||
+               addr_type == eAddressTypeInvalid)
       addr_value = LLDB_INVALID_ADDRESS;
   }
   return addr_value;
@@ -3013,8 +3049,12 @@ lldb::ValueObjectSP 
ValueObject::CastScalarToBasicType(CompilerType type,
                                                     GetValueAsUnsigned(0) != 
0);
     }
     if (GetCompilerType().IsFloat()) {
-      return ValueObject::CreateValueObjectFromBool(
-          target, !GetValueAsFloat().isZero());
+      auto value_or_err = GetValueAsAPFloat();
+      if (value_or_err)
+        return ValueObject::CreateValueObjectFromBool(target,
+                                                      !value_or_err->isZero());
+      else // TODO: Figure out the right thing to do in error case..
+        return GetSP();
     }
   }
   if (type.IsInteger()) {
@@ -3022,8 +3062,12 @@ lldb::ValueObjectSP 
ValueObject::CastScalarToBasicType(CompilerType type,
       uint64_t byte_size = 0;
       if (auto temp = type.GetByteSize(target.get()))
         byte_size = temp.value();
-      llvm::APSInt ext = GetValueAsAPSInt().extOrTrunc(byte_size * CHAR_BIT);
-      return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+      auto value_or_err = GetValueAsAPSInt();
+      if (value_or_err) {
+        llvm::APSInt ext = value_or_err->extOrTrunc(byte_size * CHAR_BIT);
+        return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+      } else // TODO: Figure out the right thing to do in error case..
+        return GetSP();
     }
     if (GetCompilerType().IsFloat()) {
       uint64_t byte_size = 0;
@@ -3031,34 +3075,46 @@ lldb::ValueObjectSP 
ValueObject::CastScalarToBasicType(CompilerType type,
         byte_size = temp.value();
       llvm::APSInt integer(byte_size * CHAR_BIT, !type.IsSigned());
       bool is_exact;
-      llvm::APFloatBase::opStatus status = GetValueAsFloat().convertToInteger(
-          integer, llvm::APFloat::rmTowardZero, &is_exact);
-
-      // Casting floating point values that are out of bounds of the target 
type
-      // is undefined behaviour.
-      if (status & llvm::APFloatBase::opInvalidOp) {
-        error.SetErrorString("invalid type cast detected");
-      }
+      auto value_or_err = GetValueAsAPFloat();
+      if (value_or_err) {
+        llvm::APFloatBase::opStatus status = value_or_err->convertToInteger(
+            integer, llvm::APFloat::rmTowardZero, &is_exact);
+
+        // Casting floating point values that are out of bounds of the target
+        // type is undefined behaviour.
+        if (status & llvm::APFloatBase::opInvalidOp) {
+          error.SetErrorString("invalid type cast detected");
+        }
 
-      return ValueObject::CreateValueObjectFromAPInt(target, integer, type);
+        return ValueObject::CreateValueObjectFromAPInt(target, integer, type);
+      } else // TODO: Figure out the right thing to do in error case..
+        return GetSP();
     }
   }
   if (type.IsFloat()) {
     if (GetCompilerType().IsInteger()) {
-      Scalar scalar_int(GetValueAsAPSInt());
-      llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
-          type.GetCanonicalType().GetBasicTypeEnumeration());
-      return ValueObject::CreateValueObjectFromAPFloat(target, f, type);
+      auto value_or_err = GetValueAsAPSInt();
+      if (value_or_err) {
+        Scalar scalar_int(*value_or_err);
+        llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
+            type.GetCanonicalType().GetBasicTypeEnumeration());
+        return ValueObject::CreateValueObjectFromAPFloat(target, f, type);
+      } else // TODO: Figure out the right thing to do in error case..
+        return GetSP();
     }
     if (GetCompilerType().IsFloat()) {
-      Scalar scalar_float(GetValueAsFloat());
-      llvm::APFloat f = scalar_float.CreateAPFloatFromAPFloat(
-          type.GetCanonicalType().GetBasicTypeEnumeration());
-      return ValueObject::CreateValueObjectFromAPFloat(target, f, type);
+      auto value_or_err = GetValueAsAPFloat();
+      if (value_or_err) {
+        Scalar scalar_float(*value_or_err);
+        llvm::APFloat f = scalar_float.CreateAPFloatFromAPFloat(
+            type.GetCanonicalType().GetBasicTypeEnumeration());
+        return ValueObject::CreateValueObjectFromAPFloat(target, f, type);
+      } else // TODO: Figure out the right thing to do in error case..
+        return GetSP();
     }
   }
-  assert(false && "invalid target type: must be a scalar");
-  return lldb::ValueObjectSP();
+  // TODO: Set error message.
+  return GetSP();
 }
 
 lldb::ValueObjectSP ValueObject::CastEnumToBasicType(CompilerType type) {
@@ -3076,19 +3132,22 @@ lldb::ValueObjectSP 
ValueObject::CastEnumToBasicType(CompilerType type) {
   if (auto temp = type.GetByteSize(target.get()))
     byte_size = temp.value();
   // Get the value as APSInt and extend or truncate it to the requested size.
-  llvm::APSInt ext = GetValueAsAPSInt().extOrTrunc(byte_size * CHAR_BIT);
+  auto value_or_err = GetValueAsAPSInt();
+  if (value_or_err) {
+    llvm::APSInt ext = value_or_err->extOrTrunc(byte_size * CHAR_BIT);
 
-  if (type.IsInteger()) {
-    return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
-  }
-  if (type.IsFloat()) {
-    Scalar scalar_int(ext);
-    llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
-        type.GetCanonicalType().GetBasicTypeEnumeration());
-    return ValueObject::CreateValueObjectFromAPFloat(target, f, type);
+    if (type.IsInteger()) {
+      return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+    }
+    if (type.IsFloat()) {
+      Scalar scalar_int(ext);
+      llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
+          type.GetCanonicalType().GetBasicTypeEnumeration());
+      return ValueObject::CreateValueObjectFromAPFloat(target, f, type);
+    }
   }
-  assert(false && "invalid target type: must be a scalar");
-  return lldb::ValueObjectSP();
+  // TODO: Set error message.
+  return GetSP();
 }
 
 lldb::ValueObjectSP ValueObject::CastPointerToBasicType(CompilerType type) {
@@ -3110,8 +3169,13 @@ lldb::ValueObjectSP 
ValueObject::CastPointerToBasicType(CompilerType type) {
   }
 
   // Get the value as APSInt and extend or truncate it to the requested size.
-  llvm::APSInt ext = GetValueAsAPSInt().extOrTrunc(type_byte_size * CHAR_BIT);
-  return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+  auto value_or_err = GetValueAsAPSInt();
+  if (value_or_err) {
+    llvm::APSInt ext = value_or_err->extOrTrunc(type_byte_size * CHAR_BIT);
+    return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+  }
+  // TODO: Set error message.
+  return GetSP();
 }
 
 lldb::ValueObjectSP
@@ -3127,8 +3191,13 @@ ValueObject::CastIntegerOrEnumToEnumType(CompilerType 
type) {
     byte_size = temp.value();
 
   // Get the value as APSInt and extend or truncate it to the requested size.
-  llvm::APSInt ext = GetValueAsAPSInt().extOrTrunc(byte_size * CHAR_BIT);
-  return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+  auto value_or_err = GetValueAsAPSInt();
+  if (value_or_err) {
+    llvm::APSInt ext = value_or_err->extOrTrunc(byte_size * CHAR_BIT);
+    return ValueObject::CreateValueObjectFromAPInt(target, ext, type);
+  }
+  // TODO: Set error message.
+  return GetSP();
 }
 
 lldb::ValueObjectSP ValueObject::CastFloatToEnumType(CompilerType type,
@@ -3144,16 +3213,21 @@ lldb::ValueObjectSP 
ValueObject::CastFloatToEnumType(CompilerType type,
   llvm::APSInt integer(byte_size * CHAR_BIT, !type.IsSigned());
   bool is_exact;
 
-  llvm::APFloatBase::opStatus status = GetValueAsFloat().convertToInteger(
-      integer, llvm::APFloat::rmTowardZero, &is_exact);
+  auto value_or_err = GetValueAsAPFloat();
+  if (value_or_err) {
+    llvm::APFloatBase::opStatus status = value_or_err->convertToInteger(
+        integer, llvm::APFloat::rmTowardZero, &is_exact);
 
-  // Casting floating point values that are out of bounds of the target type
-  // is undefined behaviour.
-  if (status & llvm::APFloatBase::opInvalidOp) {
-    error.SetErrorString("invalid type cast detected");
-  }
+    // Casting floating point values that are out of bounds of the target type
+    // is undefined behaviour.
+    if (status & llvm::APFloatBase::opInvalidOp) {
+      error.SetErrorString("invalid type cast detected");
+    }
 
-  return ValueObject::CreateValueObjectFromAPInt(target, integer, type);
+    return ValueObject::CreateValueObjectFromAPInt(target, integer, type);
+  }
+  // TODO: Set error message.
+  return GetSP();
 }
 
 ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() 
{}

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to