[Lldb-commits] [lldb] e692d08 - [LLDB] Add more helper functions to CompilerType class (second try). (#73472)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Dec 14 14:10:23 PST 2023
Author: cmtice
Date: 2023-12-14T14:10:19-08:00
New Revision: e692d0836003dead19070e5f7d199a48fa082f72
URL: https://github.com/llvm/llvm-project/commit/e692d0836003dead19070e5f7d199a48fa082f72
DIFF: https://github.com/llvm/llvm-project/commit/e692d0836003dead19070e5f7d199a48fa082f72.diff
LOG: [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).
Added:
Modified:
lldb/include/lldb/Symbol/CompilerType.h
lldb/source/Symbol/CompilerType.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h
index 0a9533a1ac0efc..414c44275aaafc 100644
--- a/lldb/include/lldb/Symbol/CompilerType.h
+++ b/lldb/include/lldb/Symbol/CompilerType.h
@@ -194,6 +194,60 @@ class CompilerType {
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.
diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index 78cc8dad94a9c5..76b79daa6ac154 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -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 {
More information about the lldb-commits
mailing list