================
@@ -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");
----------------
bulbazord wrote:

Same w/ these assertions

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