llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Ilia Kuklin (kuilpd) <details> <summary>Changes</summary> Add a function `IsValidDereferenceType` to TypeSystem. TypeSystemClang now allows arrays to be dereferenced. --- Full diff: https://github.com/llvm/llvm-project/pull/135843.diff 7 Files Affected: - (modified) lldb/include/lldb/Symbol/CompilerType.h (+8) - (modified) lldb/include/lldb/Symbol/TypeSystem.h (+7) - (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+17) - (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h (+7) - (modified) lldb/source/Symbol/CompilerType.cpp (+15) - (modified) lldb/source/ValueObject/ValueObject.cpp (+31-33) - (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/optional/TestDataFormatterGenericOptional.py (+1-1) ``````````diff diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index 671b5314c24a2..f02a415afd12c 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -433,6 +433,14 @@ class CompilerType { CompilerDecl GetStaticFieldWithName(llvm::StringRef name) 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, 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 9e9edc09a0846..7c58805342993 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -364,6 +364,13 @@ class TypeSystem : public PluginInterface, return CompilerDecl(); } + virtual llvm::Expected<CompilerType> GetDereferencedType( + lldb::opaque_compiler_type_t type, 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) = 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, diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 59292f4b24af3..5c1b98509892e 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -6201,6 +6201,23 @@ uint32_t TypeSystemClang::GetNumPointeeChildren(clang::QualType type) { return 0; } +llvm::Expected<CompilerType> TypeSystemClang::GetDereferencedType( + lldb::opaque_compiler_type_t type, 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) { + 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; + return GetChildCompilerTypeAtIndex( + 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( 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 442f88a5b79ae..ab74027cc75c4 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -889,6 +889,13 @@ class TypeSystemClang : public TypeSystem { static uint32_t GetNumPointeeChildren(clang::QualType type); + llvm::Expected<CompilerType> GetDereferencedType( + lldb::opaque_compiler_type_t type, 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) 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 8e89d006d08d3..998822708fe21 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -893,6 +893,21 @@ CompilerDecl CompilerType::GetStaticFieldWithName(llvm::StringRef name) const { return CompilerDecl(); } +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 { + 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); + 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 8741cb7343166..b023dbf118d78 100644 --- a/lldb/source/ValueObject/ValueObject.cpp +++ b/lldb/source/ValueObject/ValueObject.cpp @@ -2850,37 +2850,37 @@ 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) { - 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; + 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; + 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) + CompilerType child_compiler_type; + 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); + + 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), - child_compiler_type_or_err.takeError(), + llvm::createStringError(deref_error), "could not find child: {0}"); - else - child_compiler_type = *child_compiler_type_or_err; + } + } 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()) @@ -2889,8 +2889,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 @@ -2910,12 +2909,11 @@ 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); } } } - } else if (HasSyntheticValue()) { m_deref_valobj = GetSyntheticValue()->GetChildMemberWithName("$$dereference$$").get(); @@ -2930,13 +2928,13 @@ ValueObjectSP ValueObject::Dereference(Status &error) { StreamString strm; GetExpressionPath(strm); - if (is_pointer_or_reference_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++"]) `````````` </details> https://github.com/llvm/llvm-project/pull/135843 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits