https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/135843
>From 7cca4bf228ab2b882a1a6487eb24948cba9e5b12 Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <ikuk...@accesssoftek.com> Date: Wed, 16 Apr 2025 00:30:51 +0500 Subject: [PATCH 1/4] [lldb][TypeSystemClang] Add a function `IsValidDereferenceType` to TypeSystem to allow arrays to be dereferenced in C/C++. --- lldb/include/lldb/Symbol/CompilerType.h | 2 ++ lldb/include/lldb/Symbol/TypeSystem.h | 2 ++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 9 +++++++++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h | 2 ++ lldb/source/Symbol/CompilerType.cpp | 7 +++++++ lldb/source/ValueObject/ValueObject.cpp | 7 ++++--- 6 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index fdbc2057ac10f..3d726fca5a16c 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -186,6 +186,8 @@ class CompilerType { bool IsReferenceType(CompilerType *pointee_type = nullptr, bool *is_rvalue = nullptr) const; + bool IsValidDereferenceType() const; + bool ShouldTreatScalarValueAsAddress() const; bool IsScalarType() const; diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index df87fea32b72a..753352b45e2d9 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -489,6 +489,8 @@ class TypeSystem : public PluginInterface, virtual bool IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue) = 0; + virtual bool IsValidDereferenceType(lldb::opaque_compiler_type_t type) = 0; + virtual bool ShouldTreatScalarValueAsAddress(lldb::opaque_compiler_type_t type) { return IsPointerOrReferenceType(type, nullptr); diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index cb0ecd6ebd406..4165e08a63302 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -3443,6 +3443,13 @@ bool TypeSystemClang::IsReferenceType(lldb::opaque_compiler_type_t type, return false; } +bool TypeSystemClang::IsValidDereferenceType( + lldb::opaque_compiler_type_t type) { + CompilerType compiler_type = GetType(clang::QualType::getFromOpaquePtr(type)); + return compiler_type.IsPointerOrReferenceType() || + compiler_type.IsArrayType(); +} + bool TypeSystemClang::IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) { if (type) { @@ -6544,6 +6551,8 @@ llvm::Expected<CompilerType> TypeSystemClang::GetChildCompilerTypeAtIndex( return size_or_err.takeError(); child_byte_size = *size_or_err; child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; + if (idx == 0) + child_is_deref_of_parent = true; return element_type; } } diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 93933846d114d..8924cf99e8f7f 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -716,6 +716,8 @@ class TypeSystemClang : public TypeSystem { bool IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue) override; + bool IsValidDereferenceType(lldb::opaque_compiler_type_t type) override; + bool IsScalarType(lldb::opaque_compiler_type_t type) override; bool IsTypedefType(lldb::opaque_compiler_type_t type) override; diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp index 90c4dbf0c6206..183a6aa0ba6d4 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -233,6 +233,13 @@ bool CompilerType::IsReferenceType(CompilerType *pointee_type, return false; } +bool CompilerType::IsValidDereferenceType() const { + if (IsValid()) + if (auto type_system_sp = GetTypeSystem()) + return type_system_sp->IsValidDereferenceType(m_type); + return false; +} + bool CompilerType::ShouldTreatScalarValueAsAddress() const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp index d5e0d462c3759..2c95e27c6e2c9 100644 --- a/lldb/source/ValueObject/ValueObject.cpp +++ b/lldb/source/ValueObject/ValueObject.cpp @@ -2794,8 +2794,9 @@ ValueObjectSP ValueObject::Dereference(Status &error) { if (m_deref_valobj) return m_deref_valobj->GetSP(); - const bool is_pointer_or_reference_type = IsPointerOrReferenceType(); - if (is_pointer_or_reference_type) { + const bool is_valid_dereference_type = + GetCompilerType().IsValidDereferenceType(); + if (is_valid_dereference_type) { bool omit_empty_base_classes = true; bool ignore_array_bounds = false; @@ -2871,7 +2872,7 @@ ValueObjectSP ValueObject::Dereference(Status &error) { StreamString strm; GetExpressionPath(strm); - if (is_pointer_or_reference_type) + if (is_valid_dereference_type) error = Status::FromErrorStringWithFormat( "dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetData()); >From 1ca8c5fbb44f9ed2909a298ac9994445942983bb Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <ikuk...@accesssoftek.com> Date: Thu, 24 Apr 2025 03:34:11 +0500 Subject: [PATCH 2/4] Add a function `GetDereferencedType` instead. --- lldb/include/lldb/Symbol/CompilerType.h | 11 +++- lldb/include/lldb/Symbol/TypeSystem.h | 11 +++- .../TypeSystem/Clang/TypeSystemClang.cpp | 26 +++++--- .../TypeSystem/Clang/TypeSystemClang.h | 11 +++- lldb/source/Symbol/CompilerType.cpp | 26 +++++--- lldb/source/ValueObject/ValueObject.cpp | 59 +++++++++---------- 6 files changed, 94 insertions(+), 50 deletions(-) diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index 3d726fca5a16c..9e738cedc72b2 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -186,8 +186,6 @@ class CompilerType { bool IsReferenceType(CompilerType *pointee_type = nullptr, bool *is_rvalue = nullptr) const; - bool IsValidDereferenceType() const; - bool ShouldTreatScalarValueAsAddress() const; bool IsScalarType() const; @@ -435,6 +433,15 @@ class CompilerType { CompilerDecl GetStaticFieldWithName(llvm::StringRef name) const; + llvm::Expected<CompilerType> GetDereferencedType( + ExecutionContext *exe_ctx, bool transparent_pointers, + bool omit_empty_base_classes, bool ignore_array_bounds, + std::string &child_name, uint32_t &child_byte_size, + int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, + bool &child_is_deref_of_parent, ValueObject *valobj, + uint64_t &language_flags, bool &type_valid) const; + llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, bool ignore_array_bounds, diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index 753352b45e2d9..211f6e04e444b 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -364,6 +364,15 @@ class TypeSystem : public PluginInterface, return CompilerDecl(); } + virtual llvm::Expected<CompilerType> GetDereferencedType( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + bool transparent_pointers, bool omit_empty_base_classes, + bool ignore_array_bounds, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, + ValueObject *valobj, uint64_t &language_flags, bool &type_valid) = 0; + virtual llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, @@ -489,8 +498,6 @@ class TypeSystem : public PluginInterface, virtual bool IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue) = 0; - virtual bool IsValidDereferenceType(lldb::opaque_compiler_type_t type) = 0; - virtual bool ShouldTreatScalarValueAsAddress(lldb::opaque_compiler_type_t type) { return IsPointerOrReferenceType(type, nullptr); diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 4165e08a63302..27914da27cea2 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -3443,13 +3443,6 @@ bool TypeSystemClang::IsReferenceType(lldb::opaque_compiler_type_t type, return false; } -bool TypeSystemClang::IsValidDereferenceType( - lldb::opaque_compiler_type_t type) { - CompilerType compiler_type = GetType(clang::QualType::getFromOpaquePtr(type)); - return compiler_type.IsPointerOrReferenceType() || - compiler_type.IsArrayType(); -} - bool TypeSystemClang::IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) { if (type) { @@ -6187,6 +6180,25 @@ uint32_t TypeSystemClang::GetNumPointeeChildren(clang::QualType type) { return 0; } +llvm::Expected<CompilerType> TypeSystemClang::GetDereferencedType( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + bool transparent_pointers, bool omit_empty_base_classes, + bool ignore_array_bounds, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, + ValueObject *valobj, uint64_t &language_flags, bool &type_valid) { + type_valid = IsPointerOrReferenceType(type, nullptr) || + IsArrayType(type, nullptr, nullptr, nullptr); + if (!type_valid) + return CompilerType(); + return GetChildCompilerTypeAtIndex( + type, exe_ctx, 0, transparent_pointers, omit_empty_base_classes, + ignore_array_bounds, child_name, child_byte_size, child_byte_offset, + child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, + child_is_deref_of_parent, valobj, language_flags); +} + llvm::Expected<CompilerType> TypeSystemClang::GetChildCompilerTypeAtIndex( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 8924cf99e8f7f..89d93cfeb2d13 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -716,8 +716,6 @@ class TypeSystemClang : public TypeSystem { bool IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue) override; - bool IsValidDereferenceType(lldb::opaque_compiler_type_t type) override; - bool IsScalarType(lldb::opaque_compiler_type_t type) override; bool IsTypedefType(lldb::opaque_compiler_type_t type) override; @@ -891,6 +889,15 @@ class TypeSystemClang : public TypeSystem { static uint32_t GetNumPointeeChildren(clang::QualType type); + llvm::Expected<CompilerType> GetDereferencedType( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + bool transparent_pointers, bool omit_empty_base_classes, + bool ignore_array_bounds, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, + ValueObject *valobj, uint64_t &language_flags, bool &type_valid) override; + llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp index 183a6aa0ba6d4..5dd0301d9adf9 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -233,13 +233,6 @@ bool CompilerType::IsReferenceType(CompilerType *pointee_type, return false; } -bool CompilerType::IsValidDereferenceType() const { - if (IsValid()) - if (auto type_system_sp = GetTypeSystem()) - return type_system_sp->IsValidDereferenceType(m_type); - return false; -} - bool CompilerType::ShouldTreatScalarValueAsAddress() const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) @@ -900,6 +893,25 @@ CompilerDecl CompilerType::GetStaticFieldWithName(llvm::StringRef name) const { return CompilerDecl(); } +llvm::Expected<CompilerType> CompilerType::GetDereferencedType( + ExecutionContext *exe_ctx, bool transparent_pointers, + bool omit_empty_base_classes, bool ignore_array_bounds, + std::string &child_name, uint32_t &child_byte_size, + int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, + bool &child_is_deref_of_parent, ValueObject *valobj, + uint64_t &language_flags, bool &type_valid) const { + if (IsValid()) + if (auto type_system_sp = GetTypeSystem()) + return type_system_sp->GetDereferencedType( + m_type, exe_ctx, transparent_pointers, omit_empty_base_classes, + ignore_array_bounds, child_name, child_byte_size, child_byte_offset, + child_bitfield_bit_size, child_bitfield_bit_offset, + child_is_base_class, child_is_deref_of_parent, valobj, language_flags, + type_valid); + return CompilerType(); +} + llvm::Expected<CompilerType> CompilerType::GetChildCompilerTypeAtIndex( ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, bool ignore_array_bounds, diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp index 2c95e27c6e2c9..a8b03f9e245de 100644 --- a/lldb/source/ValueObject/ValueObject.cpp +++ b/lldb/source/ValueObject/ValueObject.cpp @@ -2794,38 +2794,38 @@ ValueObjectSP ValueObject::Dereference(Status &error) { if (m_deref_valobj) return m_deref_valobj->GetSP(); - const bool is_valid_dereference_type = - GetCompilerType().IsValidDereferenceType(); - if (is_valid_dereference_type) { - bool omit_empty_base_classes = true; - bool ignore_array_bounds = false; - - std::string child_name_str; - uint32_t child_byte_size = 0; - int32_t child_byte_offset = 0; - uint32_t child_bitfield_bit_size = 0; - uint32_t child_bitfield_bit_offset = 0; - bool child_is_base_class = false; - bool child_is_deref_of_parent = false; - const bool transparent_pointers = false; - CompilerType compiler_type = GetCompilerType(); - uint64_t language_flags = 0; + bool omit_empty_base_classes = true; + bool ignore_array_bounds = false; + std::string child_name_str; + uint32_t child_byte_size = 0; + int32_t child_byte_offset = 0; + uint32_t child_bitfield_bit_size = 0; + uint32_t child_bitfield_bit_offset = 0; + bool child_is_base_class = false; + bool child_is_deref_of_parent = false; + const bool transparent_pointers = false; + CompilerType compiler_type = GetCompilerType(); + uint64_t language_flags = 0; + bool is_valid_dereference_type = false; - ExecutionContext exe_ctx(GetExecutionContextRef()); + ExecutionContext exe_ctx(GetExecutionContextRef()); - CompilerType child_compiler_type; - auto child_compiler_type_or_err = compiler_type.GetChildCompilerTypeAtIndex( - &exe_ctx, 0, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, this, language_flags); - if (!child_compiler_type_or_err) - LLDB_LOG_ERROR(GetLog(LLDBLog::Types), - child_compiler_type_or_err.takeError(), - "could not find child: {0}"); - else - child_compiler_type = *child_compiler_type_or_err; + CompilerType child_compiler_type; + auto child_compiler_type_or_err = compiler_type.GetDereferencedType( + &exe_ctx, transparent_pointers, omit_empty_base_classes, + ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset, + child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, + child_is_deref_of_parent, this, language_flags, + is_valid_dereference_type); + if (!child_compiler_type_or_err && is_valid_dereference_type) + LLDB_LOG_ERROR(GetLog(LLDBLog::Types), + child_compiler_type_or_err.takeError(), + "could not find child: {0}"); + else + child_compiler_type = *child_compiler_type_or_err; + + if (is_valid_dereference_type) { if (child_compiler_type && child_byte_size) { ConstString child_name; if (!child_name_str.empty()) @@ -2860,7 +2860,6 @@ ValueObjectSP ValueObject::Dereference(Status &error) { } } } - } else if (IsSynthetic()) { m_deref_valobj = GetChildMemberWithName("$$dereference$$").get(); } >From 69c0ddc9ab3125857a6de663b3ac3ecc947d4477 Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <ikuk...@accesssoftek.com> Date: Thu, 24 Apr 2025 21:31:06 +0500 Subject: [PATCH 3/4] Remove unnecessary arguments, add error output from `GetDereferencedType`. --- lldb/include/lldb/Symbol/CompilerType.h | 15 ++++---- lldb/include/lldb/Symbol/TypeSystem.h | 8 ++--- .../TypeSystem/Clang/TypeSystemClang.cpp | 20 +++++------ .../TypeSystem/Clang/TypeSystemClang.h | 8 ++--- lldb/source/Symbol/CompilerType.cpp | 18 ++++------ lldb/source/ValueObject/ValueObject.cpp | 36 +++++++++---------- .../TestDataFormatterGenericOptional.py | 2 +- 7 files changed, 46 insertions(+), 61 deletions(-) diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index 9e738cedc72b2..a2f077dc9d8ac 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -433,14 +433,13 @@ class CompilerType { CompilerDecl GetStaticFieldWithName(llvm::StringRef name) const; - llvm::Expected<CompilerType> GetDereferencedType( - ExecutionContext *exe_ctx, bool transparent_pointers, - bool omit_empty_base_classes, bool ignore_array_bounds, - std::string &child_name, uint32_t &child_byte_size, - int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, - uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, - bool &child_is_deref_of_parent, ValueObject *valobj, - uint64_t &language_flags, bool &type_valid) const; + llvm::Expected<CompilerType> + GetDereferencedType(ExecutionContext *exe_ctx, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, ValueObject *valobj, + uint64_t &language_flags, bool &type_valid) const; llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index 211f6e04e444b..cec3ec418dc51 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -366,11 +366,9 @@ class TypeSystem : public PluginInterface, virtual llvm::Expected<CompilerType> GetDereferencedType( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, + std::string &child_name, uint32_t &child_byte_size, + int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, ValueObject *valobj, uint64_t &language_flags, bool &type_valid) = 0; virtual llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 27914da27cea2..2874eafca66ab 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -6182,21 +6182,19 @@ uint32_t TypeSystemClang::GetNumPointeeChildren(clang::QualType type) { llvm::Expected<CompilerType> TypeSystemClang::GetDereferencedType( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, + std::string &child_name, uint32_t &child_byte_size, + int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, ValueObject *valobj, uint64_t &language_flags, bool &type_valid) { type_valid = IsPointerOrReferenceType(type, nullptr) || IsArrayType(type, nullptr, nullptr, nullptr); if (!type_valid) - return CompilerType(); + return llvm::createStringError("not a pointer, reference or array type"); + bool child_is_deref_of_parent; return GetChildCompilerTypeAtIndex( - type, exe_ctx, 0, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, valobj, language_flags); + type, exe_ctx, 0, false, true, false, child_name, child_byte_size, + child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, + child_is_base_class, child_is_deref_of_parent, valobj, language_flags); } llvm::Expected<CompilerType> TypeSystemClang::GetChildCompilerTypeAtIndex( @@ -6563,8 +6561,6 @@ llvm::Expected<CompilerType> TypeSystemClang::GetChildCompilerTypeAtIndex( return size_or_err.takeError(); child_byte_size = *size_or_err; child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; - if (idx == 0) - child_is_deref_of_parent = true; return element_type; } } diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 89d93cfeb2d13..3d92a4120321d 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -891,11 +891,9 @@ class TypeSystemClang : public TypeSystem { llvm::Expected<CompilerType> GetDereferencedType( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, + std::string &child_name, uint32_t &child_byte_size, + int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, ValueObject *valobj, uint64_t &language_flags, bool &type_valid) override; llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp index 5dd0301d9adf9..3311513922707 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -894,21 +894,17 @@ CompilerDecl CompilerType::GetStaticFieldWithName(llvm::StringRef name) const { } llvm::Expected<CompilerType> CompilerType::GetDereferencedType( - ExecutionContext *exe_ctx, bool transparent_pointers, - bool omit_empty_base_classes, bool ignore_array_bounds, - std::string &child_name, uint32_t &child_byte_size, - int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, - uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, - bool &child_is_deref_of_parent, ValueObject *valobj, - uint64_t &language_flags, bool &type_valid) const { + ExecutionContext *exe_ctx, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, ValueObject *valobj, uint64_t &language_flags, + bool &type_valid) const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetDereferencedType( - m_type, exe_ctx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, + m_type, exe_ctx, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, - child_is_base_class, child_is_deref_of_parent, valobj, language_flags, - type_valid); + child_is_base_class, valobj, language_flags, type_valid); return CompilerType(); } diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp index a8b03f9e245de..5e6dcf7718e16 100644 --- a/lldb/source/ValueObject/ValueObject.cpp +++ b/lldb/source/ValueObject/ValueObject.cpp @@ -2794,16 +2794,12 @@ ValueObjectSP ValueObject::Dereference(Status &error) { if (m_deref_valobj) return m_deref_valobj->GetSP(); - bool omit_empty_base_classes = true; - bool ignore_array_bounds = false; std::string child_name_str; uint32_t child_byte_size = 0; int32_t child_byte_offset = 0; uint32_t child_bitfield_bit_size = 0; uint32_t child_bitfield_bit_offset = 0; bool child_is_base_class = false; - bool child_is_deref_of_parent = false; - const bool transparent_pointers = false; CompilerType compiler_type = GetCompilerType(); uint64_t language_flags = 0; bool is_valid_dereference_type = false; @@ -2812,17 +2808,20 @@ ValueObjectSP ValueObject::Dereference(Status &error) { CompilerType child_compiler_type; auto child_compiler_type_or_err = compiler_type.GetDereferencedType( - &exe_ctx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset, + &exe_ctx, child_name_str, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, this, language_flags, - is_valid_dereference_type); + this, language_flags, is_valid_dereference_type); - if (!child_compiler_type_or_err && is_valid_dereference_type) - LLDB_LOG_ERROR(GetLog(LLDBLog::Types), - child_compiler_type_or_err.takeError(), - "could not find child: {0}"); - else + std::string deref_error; + if (!child_compiler_type_or_err) { + auto err = child_compiler_type_or_err.takeError(); + if (err.isA<llvm::StringError>()) { + deref_error = llvm::toString(std::move(err)); + LLDB_LOG_ERROR(GetLog(LLDBLog::Types), + llvm::createStringError(deref_error), + "could not find child: {0}"); + } + } else child_compiler_type = *child_compiler_type_or_err; if (is_valid_dereference_type) { @@ -2834,8 +2833,7 @@ ValueObjectSP ValueObject::Dereference(Status &error) { m_deref_valobj = new ValueObjectChild( *this, child_compiler_type, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, - child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid, - language_flags); + child_is_base_class, true, eAddressTypeInvalid, language_flags); } // In case of incomplete child compiler type, use the pointee type and try @@ -2855,8 +2853,8 @@ ValueObjectSP ValueObject::Dereference(Status &error) { m_deref_valobj = new ValueObjectChild( *this, child_compiler_type, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, - child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, eAddressTypeInvalid, language_flags); + child_bitfield_bit_offset, child_is_base_class, true, + eAddressTypeInvalid, language_flags); } } } @@ -2871,13 +2869,13 @@ ValueObjectSP ValueObject::Dereference(Status &error) { StreamString strm; GetExpressionPath(strm); - if (is_valid_dereference_type) + if (deref_error.empty()) error = Status::FromErrorStringWithFormat( "dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetData()); else error = Status::FromErrorStringWithFormat( - "not a pointer or reference type: (%s) %s", + "dereference failed: %s: (%s) %s", deref_error.c_str(), GetTypeName().AsCString("<invalid type>"), strm.GetData()); return ValueObjectSP(); } diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/optional/TestDataFormatterGenericOptional.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/optional/TestDataFormatterGenericOptional.py index 7dc656a7ae225..8f36edea7d727 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/optional/TestDataFormatterGenericOptional.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/optional/TestDataFormatterGenericOptional.py @@ -88,7 +88,7 @@ def cleanup(): self.expect( "frame variable *number_not_engaged", error=True, - substrs=["not a pointer or reference type"], + substrs=["dereference failed: not a"], ) @add_test_categories(["libc++"]) >From a0ebf366e0e1836b45adf2910d87e823ca6f5534 Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <ikuk...@accesssoftek.com> Date: Wed, 30 Apr 2025 21:13:44 +0500 Subject: [PATCH 4/4] Rebase & remove the separate type validity argument --- lldb/include/lldb/Symbol/CompilerType.h | 2 +- lldb/include/lldb/Symbol/TypeSystem.h | 2 +- .../TypeSystem/Clang/TypeSystemClang.cpp | 6 ++-- .../TypeSystem/Clang/TypeSystemClang.h | 2 +- lldb/source/Symbol/CompilerType.cpp | 6 ++-- lldb/source/ValueObject/ValueObject.cpp | 28 +++++++++---------- .../TestFrameVarDILPointerArithmetic.py | 6 +--- 7 files changed, 23 insertions(+), 29 deletions(-) diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index a2f077dc9d8ac..f4120e042e122 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -439,7 +439,7 @@ class CompilerType { uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, ValueObject *valobj, - uint64_t &language_flags, bool &type_valid) const; + uint64_t &language_flags) const; llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index cec3ec418dc51..33a96463a9c73 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -369,7 +369,7 @@ class TypeSystem : public PluginInterface, std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, - ValueObject *valobj, uint64_t &language_flags, bool &type_valid) = 0; + ValueObject *valobj, uint64_t &language_flags) = 0; virtual llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 2874eafca66ab..4dbe215718d2a 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -6185,9 +6185,9 @@ llvm::Expected<CompilerType> TypeSystemClang::GetDereferencedType( std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, - ValueObject *valobj, uint64_t &language_flags, bool &type_valid) { - type_valid = IsPointerOrReferenceType(type, nullptr) || - IsArrayType(type, nullptr, nullptr, nullptr); + ValueObject *valobj, uint64_t &language_flags) { + bool type_valid = IsPointerOrReferenceType(type, nullptr) || + IsArrayType(type, nullptr, nullptr, nullptr); if (!type_valid) return llvm::createStringError("not a pointer, reference or array type"); bool child_is_deref_of_parent; diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 3d92a4120321d..2440e4fbfcd7d 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -894,7 +894,7 @@ class TypeSystemClang : public TypeSystem { std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, - ValueObject *valobj, uint64_t &language_flags, bool &type_valid) override; + ValueObject *valobj, uint64_t &language_flags) override; llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp index 3311513922707..23f18abfeea7f 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -897,14 +897,14 @@ llvm::Expected<CompilerType> CompilerType::GetDereferencedType( ExecutionContext *exe_ctx, std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, ValueObject *valobj, uint64_t &language_flags, - bool &type_valid) const { + bool &child_is_base_class, ValueObject *valobj, + uint64_t &language_flags) const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetDereferencedType( m_type, exe_ctx, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, - child_is_base_class, valobj, language_flags, type_valid); + child_is_base_class, valobj, language_flags); return CompilerType(); } diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp index 5e6dcf7718e16..e3e2c0b09c9fd 100644 --- a/lldb/source/ValueObject/ValueObject.cpp +++ b/lldb/source/ValueObject/ValueObject.cpp @@ -2802,7 +2802,6 @@ ValueObjectSP ValueObject::Dereference(Status &error) { bool child_is_base_class = false; CompilerType compiler_type = GetCompilerType(); uint64_t language_flags = 0; - bool is_valid_dereference_type = false; ExecutionContext exe_ctx(GetExecutionContextRef()); @@ -2810,21 +2809,11 @@ ValueObjectSP ValueObject::Dereference(Status &error) { auto child_compiler_type_or_err = compiler_type.GetDereferencedType( &exe_ctx, child_name_str, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - this, language_flags, is_valid_dereference_type); + this, language_flags); std::string deref_error; - if (!child_compiler_type_or_err) { - auto err = child_compiler_type_or_err.takeError(); - if (err.isA<llvm::StringError>()) { - deref_error = llvm::toString(std::move(err)); - LLDB_LOG_ERROR(GetLog(LLDBLog::Types), - llvm::createStringError(deref_error), - "could not find child: {0}"); - } - } else + if (child_compiler_type_or_err) { child_compiler_type = *child_compiler_type_or_err; - - if (is_valid_dereference_type) { if (child_compiler_type && child_byte_size) { ConstString child_name; if (!child_name_str.empty()) @@ -2858,8 +2847,17 @@ ValueObjectSP ValueObject::Dereference(Status &error) { } } } - } else if (IsSynthetic()) { - m_deref_valobj = GetChildMemberWithName("$$dereference$$").get(); + } else { + auto err = child_compiler_type_or_err.takeError(); + if (err.isA<llvm::StringError>()) { + deref_error = llvm::toString(std::move(err)); + LLDB_LOG_ERROR(GetLog(LLDBLog::Types), + llvm::createStringError(deref_error), + "could not find child: {0}"); + } + if (IsSynthetic()) { + m_deref_valobj = GetChildMemberWithName("$$dereference$$").get(); + } } if (m_deref_valobj) { diff --git a/lldb/test/API/commands/frame/var-dil/basics/PointerArithmetic/TestFrameVarDILPointerArithmetic.py b/lldb/test/API/commands/frame/var-dil/basics/PointerArithmetic/TestFrameVarDILPointerArithmetic.py index d36c5fce6d43d..6753f988c4187 100644 --- a/lldb/test/API/commands/frame/var-dil/basics/PointerArithmetic/TestFrameVarDILPointerArithmetic.py +++ b/lldb/test/API/commands/frame/var-dil/basics/PointerArithmetic/TestFrameVarDILPointerArithmetic.py @@ -33,11 +33,7 @@ def test_dereference(self): self.expect_var_path("*offset_pref", True, type="int *") self.expect_var_path("**pp_int0", value="0") self.expect_var_path("&**pp_int0", type="int *") - self.expect( - "frame var '*array'", - error=True, - substrs=["not a pointer or reference type"], - ) + self.expect_var_path("*array", value="0") self.expect( "frame var '&*p_null'", error=True, _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits