mirror of
https://github.com/intel/llvm.git
synced 2026-02-03 18:44:31 +08:00
[LLDB] Add more helper functions to CompilerType class (second try). (#73472)
This adds 23 new helper functions to LLDB's CompilerType class, things
like IsSmartPtrType, IsPromotableIntegerType,
GetNumberofNonEmptyBaseClasses, and GetTemplateArgumentType (to name a
few).
It also has run clang-format on the files CompilerType.{h,cpp}.
These helper functions are needed as part of the implementation for the
Data Inspection Language, (see
https://discourse.llvm.org/t/rfc-data-inspection-language/69893).
This commit is contained in:
@@ -194,6 +194,60 @@ public:
|
||||
bool IsTypedefType() const;
|
||||
|
||||
bool IsVoidType() const;
|
||||
|
||||
/// This is used when you don't care about the signedness of the integer.
|
||||
bool IsInteger() const;
|
||||
|
||||
bool IsFloat() const;
|
||||
|
||||
/// This is used when you don't care about the signedness of the enum.
|
||||
bool IsEnumerationType() const;
|
||||
|
||||
bool IsUnscopedEnumerationType() const;
|
||||
|
||||
bool IsIntegerOrUnscopedEnumerationType() const;
|
||||
|
||||
bool IsSigned() const;
|
||||
|
||||
bool IsNullPtrType() const;
|
||||
|
||||
bool IsBoolean() const;
|
||||
|
||||
bool IsEnumerationIntegerTypeSigned() const;
|
||||
|
||||
bool IsScalarOrUnscopedEnumerationType() const;
|
||||
|
||||
bool IsPromotableIntegerType() const;
|
||||
|
||||
bool IsPointerToVoid() const;
|
||||
|
||||
bool IsRecordType() const;
|
||||
|
||||
//// Checks whether `target_base` is a virtual base of `type` (direct or
|
||||
/// indirect). If it is, stores the first virtual base type on the path from
|
||||
/// `type` to `target_type`. Parameter "virtual_base" is where the first
|
||||
/// virtual base type gets stored. Parameter "carry_virtual" is used to
|
||||
/// denote that we're in a recursive check of virtual base classes and we
|
||||
/// have already seen a virtual base class (so should only check direct
|
||||
/// base classes).
|
||||
/// Note: This may only be defined in TypeSystemClang.
|
||||
bool IsVirtualBase(CompilerType target_base, CompilerType *virtual_base,
|
||||
bool carry_virtual = false) const;
|
||||
|
||||
/// This may only be defined in TypeSystemClang.
|
||||
bool IsContextuallyConvertibleToBool() const;
|
||||
|
||||
bool IsBasicType() const;
|
||||
|
||||
std::string TypeDescription();
|
||||
|
||||
bool CompareTypes(CompilerType rhs) const;
|
||||
|
||||
const char *GetTypeTag();
|
||||
|
||||
/// Go through the base classes and count non-empty ones.
|
||||
uint32_t GetNumberOfNonEmptyBaseClasses();
|
||||
|
||||
/// \}
|
||||
|
||||
/// Type Completion.
|
||||
|
||||
@@ -302,6 +302,192 @@ bool CompilerType::IsBeingDefined() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompilerType::IsInteger() const {
|
||||
bool is_signed = false; // May be reset by the call below.
|
||||
return IsIntegerType(is_signed);
|
||||
}
|
||||
|
||||
bool CompilerType::IsFloat() const {
|
||||
uint32_t count = 0;
|
||||
bool is_complex = false;
|
||||
return IsFloatingPointType(count, is_complex);
|
||||
}
|
||||
|
||||
bool CompilerType::IsEnumerationType() const {
|
||||
bool is_signed = false; // May be reset by the call below.
|
||||
return IsEnumerationType(is_signed);
|
||||
}
|
||||
|
||||
bool CompilerType::IsUnscopedEnumerationType() const {
|
||||
return IsEnumerationType() && !IsScopedEnumerationType();
|
||||
}
|
||||
|
||||
bool CompilerType::IsIntegerOrUnscopedEnumerationType() const {
|
||||
return IsInteger() || IsUnscopedEnumerationType();
|
||||
}
|
||||
|
||||
bool CompilerType::IsSigned() const {
|
||||
return GetTypeInfo() & lldb::eTypeIsSigned;
|
||||
}
|
||||
|
||||
bool CompilerType::IsNullPtrType() const {
|
||||
return GetCanonicalType().GetBasicTypeEnumeration() ==
|
||||
lldb::eBasicTypeNullPtr;
|
||||
}
|
||||
|
||||
bool CompilerType::IsBoolean() const {
|
||||
return GetCanonicalType().GetBasicTypeEnumeration() == lldb::eBasicTypeBool;
|
||||
}
|
||||
|
||||
bool CompilerType::IsEnumerationIntegerTypeSigned() const {
|
||||
if (IsValid())
|
||||
return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompilerType::IsScalarOrUnscopedEnumerationType() const {
|
||||
return IsScalarType() || IsUnscopedEnumerationType();
|
||||
}
|
||||
|
||||
bool CompilerType::IsPromotableIntegerType() const {
|
||||
// Unscoped enums are always considered as promotable, even if their
|
||||
// underlying type does not need to be promoted (e.g. "int").
|
||||
if (IsUnscopedEnumerationType())
|
||||
return true;
|
||||
|
||||
switch (GetCanonicalType().GetBasicTypeEnumeration()) {
|
||||
case lldb::eBasicTypeBool:
|
||||
case lldb::eBasicTypeChar:
|
||||
case lldb::eBasicTypeSignedChar:
|
||||
case lldb::eBasicTypeUnsignedChar:
|
||||
case lldb::eBasicTypeShort:
|
||||
case lldb::eBasicTypeUnsignedShort:
|
||||
case lldb::eBasicTypeWChar:
|
||||
case lldb::eBasicTypeSignedWChar:
|
||||
case lldb::eBasicTypeUnsignedWChar:
|
||||
case lldb::eBasicTypeChar16:
|
||||
case lldb::eBasicTypeChar32:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm_unreachable("All cases handled above.");
|
||||
}
|
||||
|
||||
bool CompilerType::IsPointerToVoid() const {
|
||||
if (!IsValid())
|
||||
return false;
|
||||
|
||||
return IsPointerType() &&
|
||||
GetPointeeType().GetBasicTypeEnumeration() == lldb::eBasicTypeVoid;
|
||||
}
|
||||
|
||||
bool CompilerType::IsRecordType() const {
|
||||
if (!IsValid())
|
||||
return false;
|
||||
|
||||
return GetCanonicalType().GetTypeClass() &
|
||||
(lldb::eTypeClassClass | lldb::eTypeClassStruct |
|
||||
lldb::eTypeClassUnion);
|
||||
}
|
||||
|
||||
bool CompilerType::IsVirtualBase(CompilerType target_base,
|
||||
CompilerType *virtual_base,
|
||||
bool carry_virtual) const {
|
||||
if (CompareTypes(target_base))
|
||||
return carry_virtual;
|
||||
|
||||
if (!carry_virtual) {
|
||||
uint32_t num_virtual_bases = GetNumVirtualBaseClasses();
|
||||
for (uint32_t i = 0; i < num_virtual_bases; ++i) {
|
||||
uint32_t bit_offset;
|
||||
auto base = GetVirtualBaseClassAtIndex(i, &bit_offset);
|
||||
if (base.IsVirtualBase(target_base, virtual_base,
|
||||
/*carry_virtual*/ true)) {
|
||||
if (virtual_base)
|
||||
*virtual_base = base;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t num_direct_bases = GetNumDirectBaseClasses();
|
||||
for (uint32_t i = 0; i < num_direct_bases; ++i) {
|
||||
uint32_t bit_offset;
|
||||
auto base = GetDirectBaseClassAtIndex(i, &bit_offset);
|
||||
if (base.IsVirtualBase(target_base, virtual_base, carry_virtual))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompilerType::IsContextuallyConvertibleToBool() const {
|
||||
return IsScalarType() || IsUnscopedEnumerationType() || IsPointerType() ||
|
||||
IsNullPtrType() || IsArrayType();
|
||||
}
|
||||
|
||||
bool CompilerType::IsBasicType() const {
|
||||
return GetCanonicalType().GetBasicTypeEnumeration() !=
|
||||
lldb::eBasicTypeInvalid;
|
||||
}
|
||||
|
||||
std::string CompilerType::TypeDescription() {
|
||||
auto name = GetTypeName();
|
||||
auto canonical_name = GetCanonicalType().GetTypeName();
|
||||
if (name.IsEmpty() || canonical_name.IsEmpty())
|
||||
return "''"; // Should not happen, unless the input is broken somehow.
|
||||
|
||||
if (name == canonical_name)
|
||||
return llvm::formatv("'{0}'", name);
|
||||
|
||||
return llvm::formatv("'{0}' (canonically referred to as '{1}')", name,
|
||||
canonical_name);
|
||||
}
|
||||
|
||||
bool CompilerType::CompareTypes(CompilerType rhs) const {
|
||||
if (*this == rhs)
|
||||
return true;
|
||||
|
||||
const ConstString name = GetFullyUnqualifiedType().GetTypeName();
|
||||
const ConstString rhs_name = rhs.GetFullyUnqualifiedType().GetTypeName();
|
||||
return name == rhs_name;
|
||||
}
|
||||
|
||||
const char *CompilerType::GetTypeTag() {
|
||||
switch (GetTypeClass()) {
|
||||
case lldb::eTypeClassClass:
|
||||
return "class";
|
||||
case lldb::eTypeClassEnumeration:
|
||||
return "enum";
|
||||
case lldb::eTypeClassStruct:
|
||||
return "struct";
|
||||
case lldb::eTypeClassUnion:
|
||||
return "union";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
llvm_unreachable("All cases are covered by code above.");
|
||||
}
|
||||
|
||||
uint32_t CompilerType::GetNumberOfNonEmptyBaseClasses() {
|
||||
uint32_t ret = 0;
|
||||
uint32_t num_direct_bases = GetNumDirectBaseClasses();
|
||||
|
||||
for (uint32_t i = 0; i < num_direct_bases; ++i) {
|
||||
uint32_t bit_offset;
|
||||
CompilerType base_type = GetDirectBaseClassAtIndex(i, &bit_offset);
|
||||
if (base_type.GetNumFields() > 0 ||
|
||||
base_type.GetNumberOfNonEmptyBaseClasses() > 0)
|
||||
ret += 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Type Completion
|
||||
|
||||
bool CompilerType::GetCompleteType() const {
|
||||
|
||||
Reference in New Issue
Block a user