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

Reply via email to