Skip to content

Commit 9f70cd8

Browse files
authored
[LLDB] Add more helper functions to ValueObject class. (llvm#87197)
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
1 parent abcbbe7 commit 9f70cd8

File tree

4 files changed

+670
-25
lines changed

4 files changed

+670
-25
lines changed

lldb/include/lldb/Core/ValueObject.h

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,30 @@ class ValueObject {
441441

442442
virtual int64_t GetValueAsSigned(int64_t fail_value, bool *success = nullptr);
443443

444+
/// If the current ValueObject is of an appropriate type, convert the
445+
/// value to an APSInt and return that. Otherwise return an error.
446+
llvm::Expected<llvm::APSInt> GetValueAsAPSInt();
447+
448+
/// If the current ValueObject is of an appropriate type, convert the
449+
/// value to an APFloat and return that. Otherwise return an error.
450+
llvm::Expected<llvm::APFloat> GetValueAsAPFloat();
451+
452+
/// If the current ValueObject is of an appropriate type, convert the
453+
/// value to a boolean and return that. Otherwise return an error.
454+
llvm::Expected<bool> GetValueAsBool();
455+
456+
/// Update an existing integer ValueObject with a new integer value. This
457+
/// is only intended to be used with 'temporary' ValueObjects, i.e. ones that
458+
/// are not associated with program variables. It does not update program
459+
/// memory, registers, stack, etc.
460+
void SetValueFromInteger(const llvm::APInt &value, Status &error);
461+
462+
/// Update an existing integer ValueObject with an integer value created
463+
/// frome 'new_val_sp'. This is only intended to be used with 'temporary'
464+
/// ValueObjects, i.e. ones that are not associated with program variables.
465+
/// It does not update program memory, registers, stack, etc.
466+
void SetValueFromInteger(lldb::ValueObjectSP new_val_sp, Status &error);
467+
444468
virtual bool SetValueFromCString(const char *value_str, Status &error);
445469

446470
/// Return the module associated with this value object in case the value is
@@ -618,6 +642,32 @@ class ValueObject {
618642
virtual lldb::ValueObjectSP CastPointerType(const char *name,
619643
lldb::TypeSP &type_sp);
620644

645+
/// Return the target load address associated with this value object.
646+
lldb::addr_t GetLoadAddress();
647+
648+
/// Take a ValueObject whose type is an inherited class, and cast it to
649+
/// 'type', which should be one of its base classes. 'base_type_indices'
650+
/// contains the indices of direct base classes on the path from the
651+
/// ValueObject's current type to 'type'
652+
llvm::Expected<lldb::ValueObjectSP>
653+
CastDerivedToBaseType(CompilerType type,
654+
const llvm::ArrayRef<uint32_t> &base_type_indices);
655+
656+
/// Take a ValueObject whose type is a base class, and cast it to 'type',
657+
/// which should be one of its derived classes. 'base_type_indices'
658+
/// contains the indices of direct base classes on the path from the
659+
/// ValueObject's current type to 'type'
660+
llvm::Expected<lldb::ValueObjectSP> CastBaseToDerivedType(CompilerType type,
661+
uint64_t offset);
662+
663+
// Take a ValueObject that contains a scalar, enum or pointer type, and
664+
// cast it to a "basic" type (integer, float or boolean).
665+
lldb::ValueObjectSP CastToBasicType(CompilerType type);
666+
667+
// Take a ValueObject that contain an integer, float or enum, and cast it
668+
// to an enum.
669+
lldb::ValueObjectSP CastToEnumType(CompilerType type);
670+
621671
/// If this object represents a C++ class with a vtable, return an object
622672
/// that represents the virtual function table. If the object isn't a class
623673
/// with a vtable, return a valid ValueObject with the error set correctly.
@@ -659,15 +709,41 @@ class ValueObject {
659709
const ExecutionContext &exe_ctx,
660710
const EvaluateExpressionOptions &options);
661711

712+
/// Given an address either create a value object containing the value at
713+
/// that address, or create a value object containing the address itself
714+
/// (pointer value), depending on whether the parameter 'do_deref' is true or
715+
/// false.
662716
static lldb::ValueObjectSP
663717
CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
664718
const ExecutionContext &exe_ctx,
665-
CompilerType type);
719+
CompilerType type, bool do_deref = true);
666720

667721
static lldb::ValueObjectSP
668722
CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data,
669723
const ExecutionContext &exe_ctx, CompilerType type);
670724

725+
/// Create a value object containing the given APInt value.
726+
static lldb::ValueObjectSP CreateValueObjectFromAPInt(lldb::TargetSP target,
727+
const llvm::APInt &v,
728+
CompilerType type,
729+
llvm::StringRef name);
730+
731+
/// Create a value object containing the given APFloat value.
732+
static lldb::ValueObjectSP
733+
CreateValueObjectFromAPFloat(lldb::TargetSP target, const llvm::APFloat &v,
734+
CompilerType type, llvm::StringRef name);
735+
736+
/// Create a value object containing the given boolean value.
737+
static lldb::ValueObjectSP CreateValueObjectFromBool(lldb::TargetSP target,
738+
bool value,
739+
llvm::StringRef name);
740+
741+
/// Create a nullptr value object with the specified type (must be a
742+
/// nullptr type).
743+
static lldb::ValueObjectSP CreateValueObjectFromNullptr(lldb::TargetSP target,
744+
CompilerType type,
745+
llvm::StringRef name);
746+
671747
lldb::ValueObjectSP Persist();
672748

673749
/// Returns true if this is a char* or a char[] if it is a char* and
@@ -719,6 +795,10 @@ class ValueObject {
719795
ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
720796
}
721797

798+
void SetDerefValobj(ValueObject *deref) { m_deref_valobj = deref; }
799+
800+
ValueObject *GetDerefValobj() { return m_deref_valobj; }
801+
722802
void SetValueFormat(lldb::TypeFormatImplSP format) {
723803
m_type_format_sp = std::move(format);
724804
ClearUserVisibleData(eClearUserVisibleDataItemsValue);

lldb/include/lldb/Utility/Scalar.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ class Scalar {
181181

182182
long double LongDouble(long double fail_value = 0.0) const;
183183

184+
llvm::APSInt GetAPSInt() const { return m_integer; }
185+
186+
llvm::APFloat GetAPFloat() const { return m_float; }
187+
184188
Status SetValueFromCString(const char *s, lldb::Encoding encoding,
185189
size_t byte_size);
186190

lldb/source/API/SBValue.cpp

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,26 +1281,8 @@ lldb::addr_t SBValue::GetLoadAddress() {
12811281
lldb::addr_t value = LLDB_INVALID_ADDRESS;
12821282
ValueLocker locker;
12831283
lldb::ValueObjectSP value_sp(GetSP(locker));
1284-
if (value_sp) {
1285-
TargetSP target_sp(value_sp->GetTargetSP());
1286-
if (target_sp) {
1287-
const bool scalar_is_load_address = true;
1288-
AddressType addr_type;
1289-
value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1290-
if (addr_type == eAddressTypeFile) {
1291-
ModuleSP module_sp(value_sp->GetModule());
1292-
if (!module_sp)
1293-
value = LLDB_INVALID_ADDRESS;
1294-
else {
1295-
Address addr;
1296-
module_sp->ResolveFileAddress(value, addr);
1297-
value = addr.GetLoadAddress(target_sp.get());
1298-
}
1299-
} else if (addr_type == eAddressTypeHost ||
1300-
addr_type == eAddressTypeInvalid)
1301-
value = LLDB_INVALID_ADDRESS;
1302-
}
1303-
}
1284+
if (value_sp)
1285+
return value_sp->GetLoadAddress();
13041286

13051287
return value;
13061288
}

0 commit comments

Comments
 (0)