https://github.com/cmtice updated https://github.com/llvm/llvm-project/pull/73472
>From a063ebd8ee8bbd491fff3449bc20d663d2e501ea Mon Sep 17 00:00:00 2001 From: Caroline Tice <cmt...@google.com> Date: Sun, 26 Nov 2023 17:24:39 -0800 Subject: [PATCH 1/2] [LLDB] Add more helper functions to CompilerType class (second try). 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). --- lldb/include/lldb/Symbol/CompilerType.h | 56 ++++- lldb/source/Symbol/CompilerType.cpp | 285 ++++++++++++++++++++++-- 2 files changed, 320 insertions(+), 21 deletions(-) diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index 0a9533a1ac0efc1..a3331ad3269c01d 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -112,9 +112,7 @@ class CompilerType { /// Tests. /// \{ - explicit operator bool() const { - return m_type_system.lock() && m_type; - } + explicit operator bool() const { return m_type_system.lock() && m_type; } bool IsValid() const { return (bool)*this; } @@ -194,6 +192,54 @@ class CompilerType { bool IsTypedefType() const; bool IsVoidType() const; + + bool IsSmartPtrType() const; + + bool IsInteger() const; + + bool IsFloat() const; + + 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; + + bool IsVirtualBase(CompilerType target_base, CompilerType *virtual_base, + bool carry_virtual = false) const; + + bool IsContextuallyConvertibleToBool() const; + + bool IsBasicType() const; + + std::string TypeDescription(); + + bool CompareTypes(CompilerType rhs) const; + + const char *GetTypeTag(); + + uint32_t GetNumberOfNonEmptyBaseClasses(); + + CompilerType GetTemplateArgumentType(uint32_t idx); + + CompilerType GetSmartPtrPointeeType(); + /// \} /// Type Completion. @@ -436,8 +482,8 @@ class CompilerType { ExecutionContextScope *exe_scope); /// Dump to stdout. - void DumpTypeDescription(lldb::DescriptionLevel level = - lldb::eDescriptionLevelFull) const; + void DumpTypeDescription( + lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) const; /// Print a description of the type to a stream. The exact implementation /// varies, but the expectation is that eDescriptionLevelFull returns a diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp index 78cc8dad94a9c5f..854d6cab01b508e 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -54,7 +54,7 @@ bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->IsArrayType(m_type, element_type_ptr, size, - is_incomplete); + is_incomplete); if (element_type_ptr) element_type_ptr->Clear(); @@ -157,7 +157,8 @@ bool CompilerType::IsBlockPointerType( CompilerType *function_pointer_type_ptr) const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) - return type_system_sp->IsBlockPointerType(m_type, function_pointer_type_ptr); + return type_system_sp->IsBlockPointerType(m_type, + function_pointer_type_ptr); return false; } @@ -249,7 +250,7 @@ bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->IsPossibleDynamicType(m_type, dynamic_pointee_type, - check_cplusplus, check_objc); + check_cplusplus, check_objc); return false; } @@ -302,6 +303,256 @@ bool CompilerType::IsBeingDefined() const { return false; } +bool CompilerType::IsSmartPtrType() const { + // These regular expressions cover shared, unique and weak pointers both from + // stdlibc++ and libc+++. + + static llvm::Regex k_libcxx_std_unique_ptr_regex( + "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$"); + static llvm::Regex k_libcxx_std_shared_ptr_regex( + "^std::__[[:alnum:]]+::shared_ptr<.+>(( )?&)?$"); + static llvm::Regex k_libcxx_std_weak_ptr_regex( + "^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"); + // + static llvm::Regex k_libcxx_std_unique_ptr_regex_2( + "^std::unique_ptr<.+>(( )?&)?$"); + static llvm::Regex k_libcxx_std_shared_ptr_regex_2( + "^std::shared_ptr<.+>(( )?&)?$"); + static llvm::Regex k_libcxx_std_weak_ptr_regex_2( + "^std::weak_ptr<.+>(( )?&)?$"); + // + llvm::StringRef name = GetTypeName(); + return k_libcxx_std_unique_ptr_regex.match(name) || + k_libcxx_std_shared_ptr_regex.match(name) || + k_libcxx_std_weak_ptr_regex.match(name) || + k_libcxx_std_unique_ptr_regex_2.match(name) || + k_libcxx_std_shared_ptr_regex_2.match(name) || + k_libcxx_std_weak_ptr_regex_2.match(name); +} + +bool CompilerType::IsInteger() const { + // This is used when you don't care about the signedness of the integer. + bool is_signed; + 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 { + // This is used when you don't care about the signedness of the enum. + bool is_signed; + return IsEnumerationType(is_signed); +} + +bool CompilerType::IsUnscopedEnumerationType() const { + return IsEnumerationType() && !IsScopedEnumerationType(); +} + +bool CompilerType::IsIntegerOrUnscopedEnumerationType() const { + return IsInteger() || IsUnscopedEnumerationType(); +} + +bool CompilerType::IsSigned() const { + if (IsEnumerationType()) { + return IsEnumerationIntegerTypeSigned(); + } + 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; + } +} + +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); +} + +// 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`. +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 + } + if (name == canonical_name) { + return llvm::formatv("'{0}'", name); + } + return llvm::formatv("'{0}' (aka '{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()) { + // clang-format off + case lldb::eTypeClassClass: return "class"; + case lldb::eTypeClassEnumeration: return "enum"; + case lldb::eTypeClassStruct: return "struct"; + case lldb::eTypeClassUnion: return "union"; + // clang-format on + default: + return "unknown"; + } +} + +uint32_t CompilerType::GetNumberOfNonEmptyBaseClasses() { + // Go through the base classes and count non-empty ones. + 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; +} + +CompilerType CompilerType::GetTemplateArgumentType(uint32_t idx) { + CompilerType empty_type; + if (!IsValid()) + return empty_type; + + CompilerType type; + const bool expand_pack = true; + switch (GetTemplateArgumentKind(idx, true)) { + case lldb::eTemplateArgumentKindType: + type = GetTypeTemplateArgument(idx, expand_pack); + break; + case lldb::eTemplateArgumentKindIntegral: + type = GetIntegralTemplateArgument(idx, expand_pack)->type; + break; + default: + break; + } + if (type.IsValid()) + return type; + return empty_type; +} + +CompilerType CompilerType::GetSmartPtrPointeeType() { + assert(IsSmartPtrType() && + "the type should be a smart pointer (std::unique_ptr, std::shared_ptr " + "or std::weak_ptr"); + + return GetTemplateArgumentType(0); +} + // Type Completion bool CompilerType::GetCompleteType() const { @@ -336,9 +587,9 @@ ConstString CompilerType::GetDisplayTypeName() const { uint32_t CompilerType::GetTypeInfo( CompilerType *pointee_or_element_compiler_type) const { if (IsValid()) - if (auto type_system_sp = GetTypeSystem()) - return type_system_sp->GetTypeInfo(m_type, - pointee_or_element_compiler_type); + if (auto type_system_sp = GetTypeSystem()) + return type_system_sp->GetTypeInfo(m_type, + pointee_or_element_compiler_type); return 0; } @@ -362,8 +613,9 @@ void CompilerType::SetCompilerType(lldb::TypeSystemWP type_system, m_type = type; } -void CompilerType::SetCompilerType(CompilerType::TypeSystemSPWrapper type_system, - lldb::opaque_compiler_type_t type) { +void CompilerType::SetCompilerType( + CompilerType::TypeSystemSPWrapper type_system, + lldb::opaque_compiler_type_t type) { m_type_system = type_system.GetSharedPointer(); m_type = type; } @@ -589,7 +841,7 @@ uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes, - exe_ctx); + exe_ctx); return 0; } @@ -601,8 +853,7 @@ lldb::BasicType CompilerType::GetBasicTypeEnumeration() const { } void CompilerType::ForEachEnumerator( - std::function<bool(const CompilerType &integer_type, - ConstString name, + std::function<bool(const CompilerType &integer_type, ConstString name, const llvm::APSInt &value)> const &callback) const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) @@ -623,7 +874,8 @@ CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr, - bitfield_bit_size_ptr, is_bitfield_ptr); + bitfield_bit_size_ptr, + is_bitfield_ptr); return CompilerType(); } @@ -647,7 +899,7 @@ CompilerType::GetDirectBaseClassAtIndex(size_t idx, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx, - bit_offset_ptr); + bit_offset_ptr); return CompilerType(); } @@ -657,7 +909,7 @@ CompilerType::GetVirtualBaseClassAtIndex(size_t idx, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx, - bit_offset_ptr); + bit_offset_ptr); return CompilerType(); } @@ -738,7 +990,7 @@ size_t CompilerType::GetIndexOfChildMemberWithName( if (IsValid() && !name.empty()) { if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetIndexOfChildMemberWithName( - m_type, name, omit_empty_base_classes, child_indexes); + m_type, name, omit_empty_base_classes, child_indexes); } return 0; } @@ -772,7 +1024,8 @@ std::optional<CompilerType::IntegralTemplateArgument> CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) - return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack); + return type_system_sp->GetIntegralTemplateArgument(m_type, idx, + expand_pack); return std::nullopt; } >From 29cd28dc39af596a0a126dbf9cf3d1b233fc78be Mon Sep 17 00:00:00 2001 From: Caroline Tice <cmt...@google.com> Date: Wed, 29 Nov 2023 12:35:47 -0800 Subject: [PATCH 2/2] [LLDB] Add more helper functions to CompilerType class (second try). Address most of the reviewer comments: - Fix formatting issues - Add/Move Doxygen function comments in header file. - Undo clang-format changes to code that I didn't touch. - Other requested fixes. --- lldb/include/lldb/Symbol/CompilerType.h | 19 +++- lldb/source/Symbol/CompilerType.cpp | 131 +++++++++++------------- 2 files changed, 78 insertions(+), 72 deletions(-) diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index a3331ad3269c01d..274b1a60a5c6a4f 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -112,7 +112,9 @@ class CompilerType { /// Tests. /// \{ - explicit operator bool() const { return m_type_system.lock() && m_type; } + explicit operator bool() const { + return m_type_system.lock() && m_type; + } bool IsValid() const { return (bool)*this; } @@ -193,12 +195,16 @@ class CompilerType { bool IsVoidType() const; + /// This determines if the type is a shared, unique or weak pointer, either + /// from stdlibc++ or libc+++. bool IsSmartPtrType() 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; @@ -221,9 +227,15 @@ class CompilerType { 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. 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; @@ -234,6 +246,7 @@ class CompilerType { const char *GetTypeTag(); + /// Go through the base classes and count non-empty ones. uint32_t GetNumberOfNonEmptyBaseClasses(); CompilerType GetTemplateArgumentType(uint32_t idx); @@ -482,8 +495,8 @@ class CompilerType { ExecutionContextScope *exe_scope); /// Dump to stdout. - void DumpTypeDescription( - lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) const; + void DumpTypeDescription(lldb::DescriptionLevel level = + lldb::eDescriptionLevelFull) const; /// Print a description of the type to a stream. The exact implementation /// varies, but the expectation is that eDescriptionLevelFull returns a diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp index 854d6cab01b508e..089199ae5310d15 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -54,7 +54,7 @@ bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->IsArrayType(m_type, element_type_ptr, size, - is_incomplete); + is_incomplete); if (element_type_ptr) element_type_ptr->Clear(); @@ -157,8 +157,7 @@ bool CompilerType::IsBlockPointerType( CompilerType *function_pointer_type_ptr) const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) - return type_system_sp->IsBlockPointerType(m_type, - function_pointer_type_ptr); + return type_system_sp->IsBlockPointerType(m_type, function_pointer_type_ptr); return false; } @@ -250,7 +249,7 @@ bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->IsPossibleDynamicType(m_type, dynamic_pointee_type, - check_cplusplus, check_objc); + check_cplusplus, check_objc); return false; } @@ -304,35 +303,34 @@ bool CompilerType::IsBeingDefined() const { } bool CompilerType::IsSmartPtrType() const { - // These regular expressions cover shared, unique and weak pointers both from - // stdlibc++ and libc+++. - static llvm::Regex k_libcxx_std_unique_ptr_regex( + // libc++ smart pointers + static const llvm::Regex k_libcxx_std_unique_ptr_regex( "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$"); - static llvm::Regex k_libcxx_std_shared_ptr_regex( + static const llvm::Regex k_libcxx_std_shared_ptr_regex( "^std::__[[:alnum:]]+::shared_ptr<.+>(( )?&)?$"); - static llvm::Regex k_libcxx_std_weak_ptr_regex( + static const llvm::Regex k_libcxx_std_weak_ptr_regex( "^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"); - // - static llvm::Regex k_libcxx_std_unique_ptr_regex_2( + + // libstdc++ smart pointers + static const llvm::Regex k_libstdcxx_std_unique_ptr_regex( "^std::unique_ptr<.+>(( )?&)?$"); - static llvm::Regex k_libcxx_std_shared_ptr_regex_2( + static const llvm::Regex k_libstdcxx_std_shared_ptr_regex( "^std::shared_ptr<.+>(( )?&)?$"); - static llvm::Regex k_libcxx_std_weak_ptr_regex_2( + static const llvm::Regex k_libstdcxx_std_weak_ptr_regex( "^std::weak_ptr<.+>(( )?&)?$"); - // + llvm::StringRef name = GetTypeName(); return k_libcxx_std_unique_ptr_regex.match(name) || k_libcxx_std_shared_ptr_regex.match(name) || k_libcxx_std_weak_ptr_regex.match(name) || - k_libcxx_std_unique_ptr_regex_2.match(name) || - k_libcxx_std_shared_ptr_regex_2.match(name) || - k_libcxx_std_weak_ptr_regex_2.match(name); + k_libstdcxx_std_unique_ptr_regex.match(name) || + k_libstdcxx_std_shared_ptr_regex.match(name) || + k_libstdcxx_std_weak_ptr_regex.match(name); } bool CompilerType::IsInteger() const { - // This is used when you don't care about the signedness of the integer. - bool is_signed; + bool is_signed = false; // May be reset by the call below. return IsIntegerType(is_signed); } @@ -343,8 +341,7 @@ bool CompilerType::IsFloat() const { } bool CompilerType::IsEnumerationType() const { - // This is used when you don't care about the signedness of the enum. - bool is_signed; + bool is_signed = false; // May be reset by the call below. return IsEnumerationType(is_signed); } @@ -357,9 +354,9 @@ bool CompilerType::IsIntegerOrUnscopedEnumerationType() const { } bool CompilerType::IsSigned() const { - if (IsEnumerationType()) { + if (IsEnumerationType()) return IsEnumerationIntegerTypeSigned(); - } + return GetTypeInfo() & lldb::eTypeIsSigned; } @@ -373,9 +370,9 @@ bool CompilerType::IsBoolean() const { } bool CompilerType::IsEnumerationIntegerTypeSigned() const { - if (IsValid()) { + if (IsValid()) return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned; - } + return false; } @@ -386,9 +383,8 @@ bool CompilerType::IsScalarOrUnscopedEnumerationType() const { 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()) { + if (IsUnscopedEnumerationType()) return true; - } switch (GetCanonicalType().GetBasicTypeEnumeration()) { case lldb::eBasicTypeBool: @@ -407,6 +403,8 @@ bool CompilerType::IsPromotableIntegerType() const { default: return false; } + + llvm_unreachable("All cases handled above."); } bool CompilerType::IsPointerToVoid() const { @@ -426,15 +424,11 @@ bool CompilerType::IsRecordType() const { lldb::eTypeClassUnion); } -// 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`. bool CompilerType::IsVirtualBase(CompilerType target_base, CompilerType *virtual_base, bool carry_virtual) const { - if (CompareTypes(target_base)) { + if (CompareTypes(target_base)) return carry_virtual; - } if (!carry_virtual) { uint32_t num_virtual_bases = GetNumVirtualBaseClasses(); @@ -443,9 +437,9 @@ bool CompilerType::IsVirtualBase(CompilerType target_base, auto base = GetVirtualBaseClassAtIndex(i, &bit_offset); if (base.IsVirtualBase(target_base, virtual_base, /*carry_virtual*/ true)) { - if (virtual_base) { + if (virtual_base) *virtual_base = base; - } + return true; } } @@ -455,9 +449,8 @@ bool CompilerType::IsVirtualBase(CompilerType target_base, 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)) { + if (base.IsVirtualBase(target_base, virtual_base, carry_virtual)) return true; - } } return false; @@ -476,13 +469,14 @@ bool CompilerType::IsBasicType() const { std::string CompilerType::TypeDescription() { auto name = GetTypeName(); auto canonical_name = GetCanonicalType().GetTypeName(); - if (name.IsEmpty() || canonical_name.IsEmpty()) { - return "''"; // should not happen - } - if (name == canonical_name) { + 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}' (aka '{1}')", name, canonical_name); + + return llvm::formatv("'{0}' (canonically referred to as '{1}')", name, + canonical_name); } bool CompilerType::CompareTypes(CompilerType rhs) const { @@ -496,19 +490,21 @@ bool CompilerType::CompareTypes(CompilerType rhs) const { const char *CompilerType::GetTypeTag() { switch (GetTypeClass()) { - // clang-format off - case lldb::eTypeClassClass: return "class"; - case lldb::eTypeClassEnumeration: return "enum"; - case lldb::eTypeClassStruct: return "struct"; - case lldb::eTypeClassUnion: return "union"; - // clang-format on + 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() { - // Go through the base classes and count non-empty ones. uint32_t ret = 0; uint32_t num_direct_bases = GetNumDirectBaseClasses(); @@ -516,9 +512,8 @@ uint32_t CompilerType::GetNumberOfNonEmptyBaseClasses() { uint32_t bit_offset; CompilerType base_type = GetDirectBaseClassAtIndex(i, &bit_offset); if (base_type.GetNumFields() > 0 || - base_type.GetNumberOfNonEmptyBaseClasses() > 0) { + base_type.GetNumberOfNonEmptyBaseClasses() > 0) ret += 1; - } } return ret; } @@ -546,9 +541,9 @@ CompilerType CompilerType::GetTemplateArgumentType(uint32_t idx) { } CompilerType CompilerType::GetSmartPtrPointeeType() { - assert(IsSmartPtrType() && - "the type should be a smart pointer (std::unique_ptr, std::shared_ptr " - "or std::weak_ptr"); + if (!IsSmartPtrType()) + // TODO: Should consider issuing a warning here. + return GetPointeeType(); return GetTemplateArgumentType(0); } @@ -587,9 +582,9 @@ ConstString CompilerType::GetDisplayTypeName() const { uint32_t CompilerType::GetTypeInfo( CompilerType *pointee_or_element_compiler_type) const { if (IsValid()) - if (auto type_system_sp = GetTypeSystem()) - return type_system_sp->GetTypeInfo(m_type, - pointee_or_element_compiler_type); + if (auto type_system_sp = GetTypeSystem()) + return type_system_sp->GetTypeInfo(m_type, + pointee_or_element_compiler_type); return 0; } @@ -613,9 +608,8 @@ void CompilerType::SetCompilerType(lldb::TypeSystemWP type_system, m_type = type; } -void CompilerType::SetCompilerType( - CompilerType::TypeSystemSPWrapper type_system, - lldb::opaque_compiler_type_t type) { +void CompilerType::SetCompilerType(CompilerType::TypeSystemSPWrapper type_system, + lldb::opaque_compiler_type_t type) { m_type_system = type_system.GetSharedPointer(); m_type = type; } @@ -841,7 +835,7 @@ uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes, - exe_ctx); + exe_ctx); return 0; } @@ -853,7 +847,8 @@ lldb::BasicType CompilerType::GetBasicTypeEnumeration() const { } void CompilerType::ForEachEnumerator( - std::function<bool(const CompilerType &integer_type, ConstString name, + std::function<bool(const CompilerType &integer_type, + ConstString name, const llvm::APSInt &value)> const &callback) const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) @@ -874,8 +869,7 @@ CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr, - bitfield_bit_size_ptr, - is_bitfield_ptr); + bitfield_bit_size_ptr, is_bitfield_ptr); return CompilerType(); } @@ -899,7 +893,7 @@ CompilerType::GetDirectBaseClassAtIndex(size_t idx, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx, - bit_offset_ptr); + bit_offset_ptr); return CompilerType(); } @@ -909,7 +903,7 @@ CompilerType::GetVirtualBaseClassAtIndex(size_t idx, if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx, - bit_offset_ptr); + bit_offset_ptr); return CompilerType(); } @@ -990,7 +984,7 @@ size_t CompilerType::GetIndexOfChildMemberWithName( if (IsValid() && !name.empty()) { if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetIndexOfChildMemberWithName( - m_type, name, omit_empty_base_classes, child_indexes); + m_type, name, omit_empty_base_classes, child_indexes); } return 0; } @@ -1024,8 +1018,7 @@ std::optional<CompilerType::IntegralTemplateArgument> CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) - return type_system_sp->GetIntegralTemplateArgument(m_type, idx, - expand_pack); + return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack); return std::nullopt; } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits