[Lldb-commits] [lldb] [lldb] Add SBType::FindNestedType() function (PR #68705)

Vlad Serebrennikov via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 12 22:57:11 PDT 2023


https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/68705

>From ca4d1bbdeb4ea541199e3db3518b35eb2d5a8cad Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Tue, 10 Oct 2023 15:07:56 +0300
Subject: [PATCH 01/12] [lldb] Add SBType::FindNestedType() function

---
 lldb/bindings/interface/SBTypeDocstrings.i          |  7 +++++++
 lldb/include/lldb/API/SBType.h                      |  2 ++
 lldb/include/lldb/Symbol/Type.h                     |  2 ++
 lldb/include/lldb/Symbol/TypeSystem.h               |  4 ++++
 lldb/source/API/SBType.cpp                          |  9 +++++++++
 .../Plugins/TypeSystem/Clang/TypeSystemClang.cpp    |  4 ++++
 .../Plugins/TypeSystem/Clang/TypeSystemClang.h      |  2 ++
 lldb/source/Symbol/Type.cpp                         | 13 +++++++++++++
 lldb/source/Symbol/TypeSystem.cpp                   |  4 ++++
 9 files changed, 47 insertions(+)

diff --git a/lldb/bindings/interface/SBTypeDocstrings.i b/lldb/bindings/interface/SBTypeDocstrings.i
index 96421a6aa20104b..b4ec67da957c7d4 100644
--- a/lldb/bindings/interface/SBTypeDocstrings.i
+++ b/lldb/bindings/interface/SBTypeDocstrings.i
@@ -720,6 +720,13 @@ SBType supports the eq/ne operator. For example,::
     "
 ) lldb::SBType::GetTypeFlags;
 
+%feature("docstring",
+    "Searches for a nested type that has provided name.
+
+    Returns the type if it was found.
+    Returns invalid type if nothing was found."
+) lldb::SBType::FindNestedType;
+
 %feature("docstring",
 "Represents a list of :py:class:`SBType` s.
 
diff --git a/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h
index 5962f0c50dee14f..fa02197ff8f3940 100644
--- a/lldb/include/lldb/API/SBType.h
+++ b/lldb/include/lldb/API/SBType.h
@@ -215,6 +215,8 @@ class SBType {
   bool GetDescription(lldb::SBStream &description,
                       lldb::DescriptionLevel description_level);
 
+  lldb::SBType FindNestedType(const char *name);
+
   lldb::SBType &operator=(const lldb::SBType &rhs);
 
   bool operator==(lldb::SBType &rhs);
diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h
index 046501931d211a7..6da4aaba401fe14 100644
--- a/lldb/include/lldb/Symbol/Type.h
+++ b/lldb/include/lldb/Symbol/Type.h
@@ -313,6 +313,8 @@ class TypeImpl {
   bool GetDescription(lldb_private::Stream &strm,
                       lldb::DescriptionLevel description_level);
 
+  CompilerType FindNestedType(ConstString name);
+
 private:
   bool CheckModule(lldb::ModuleSP &module_sp) const;
   bool CheckExeModule(lldb::ModuleSP &module_sp) const;
diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index eb6e453e1aec0d0..b503b66eb528c68 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -135,6 +135,10 @@ class TypeSystem : public PluginInterface,
 
   virtual lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) = 0;
 
+  // CompilerType functions
+
+  virtual CompilerDeclContext GetCompilerDeclContextForType(const CompilerType& type);
+
   // Tests
 #ifndef NDEBUG
   /// Verify the integrity of the type to catch CompilerTypes that mix
diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index ee5b6447428098e..7fe1836ea5d670b 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -586,6 +586,15 @@ lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) {
   return eTemplateArgumentKindNull;
 }
 
+SBType SBType::FindNestedType(const char *name) {
+  LLDB_INSTRUMENT_VA(this);
+
+  if (!IsValid())
+    return SBType();
+  auto ret = SBType(m_opaque_sp->FindNestedType(ConstString(name)));
+  return ret;
+}
+
 SBTypeList::SBTypeList() : m_opaque_up(new TypeListImpl()) {
   LLDB_INSTRUMENT_VA(this);
 }
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 69cff0f35ae4ab2..b4bf3d3fdb20c1e 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2636,6 +2636,10 @@ TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
   return GetDeclContextForType(ClangUtil::GetQualType(type));
 }
 
+CompilerDeclContext TypeSystemClang::GetCompilerDeclContextForType(const CompilerType& type) {
+  return CreateDeclContext(GetDeclContextForType(type));
+}
+
 /// Aggressively desugar the provided type, skipping past various kinds of
 /// syntactic sugar and other constructs one typically wants to ignore.
 /// The \p mask argument allows one to skip certain kinds of simplifications,
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 0544de3cd33befb..806ff64ef0af76b 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -219,6 +219,8 @@ class TypeSystemClang : public TypeSystem {
 
   static clang::DeclContext *GetDeclContextForType(const CompilerType &type);
 
+  CompilerDeclContext GetCompilerDeclContextForType(const CompilerType &type) override;
+
   uint32_t GetPointerByteSize() override;
 
   clang::TranslationUnitDecl *GetTranslationUnitDecl() {
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 66284eb73cad038..724973b1fd9bd06 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -1082,6 +1082,19 @@ bool TypeImpl::GetDescription(lldb_private::Stream &strm,
   return true;
 }
 
+CompilerType TypeImpl::FindNestedType(ConstString name) {
+  auto type_system = GetTypeSystem(false);
+  auto *symbol_file = type_system->GetSymbolFile();
+  auto decl_context = type_system->GetCompilerDeclContextForType(m_static_type);
+  llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+  TypeMap search_result;
+  symbol_file->FindTypes(name, decl_context, /*max_matches*/ 1, searched_symbol_files, search_result);
+  if (search_result.Empty()) {
+    return CompilerType();
+  }
+  return search_result.GetTypeAtIndex(0)->GetFullCompilerType();
+}
+
 bool TypeMemberFunctionImpl::IsValid() {
   return m_type.IsValid() && m_kind != lldb::eMemberFunctionKindUnknown;
 }
diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
index 24f20293056501f..ce24e312f4f35e0 100644
--- a/lldb/source/Symbol/TypeSystem.cpp
+++ b/lldb/source/Symbol/TypeSystem.cpp
@@ -186,6 +186,10 @@ std::optional<llvm::json::Value> TypeSystem::ReportStatistics() {
   return std::nullopt;
 }
 
+CompilerDeclContext TypeSystem::GetCompilerDeclContextForType(const CompilerType& type) {
+  return CompilerDeclContext();
+}
+
 #pragma mark TypeSystemMap
 
 TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {}

>From f663bdcb3edc4179e2e541826c648770f9764b22 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Wed, 11 Oct 2023 07:00:00 +0300
Subject: [PATCH 02/12] Address some review feedback

---
 lldb/source/API/SBType.cpp                    | 2 +-
 lldb/source/Symbol/Type.cpp                   | 5 ++---
 lldb/test/API/python_api/type/TestTypeList.py | 5 +++++
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index 7fe1836ea5d670b..bd8e0c16f6ea7f1 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -587,7 +587,7 @@ lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) {
 }
 
 SBType SBType::FindNestedType(const char *name) {
-  LLDB_INSTRUMENT_VA(this);
+  LLDB_INSTRUMENT_VA(this, name);
 
   if (!IsValid())
     return SBType();
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 724973b1fd9bd06..e2cf9f93f01f41d 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -1083,15 +1083,14 @@ bool TypeImpl::GetDescription(lldb_private::Stream &strm,
 }
 
 CompilerType TypeImpl::FindNestedType(ConstString name) {
-  auto type_system = GetTypeSystem(false);
+  auto type_system = GetTypeSystem(/*prefer_dynamic*/ false);
   auto *symbol_file = type_system->GetSymbolFile();
   auto decl_context = type_system->GetCompilerDeclContextForType(m_static_type);
   llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
   TypeMap search_result;
   symbol_file->FindTypes(name, decl_context, /*max_matches*/ 1, searched_symbol_files, search_result);
-  if (search_result.Empty()) {
+  if (search_result.Empty())
     return CompilerType();
-  }
   return search_result.GetTypeAtIndex(0)->GetFullCompilerType();
 }
 
diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py
index c2fcadc46ec1531..f0054d561472f35 100644
--- a/lldb/test/API/python_api/type/TestTypeList.py
+++ b/lldb/test/API/python_api/type/TestTypeList.py
@@ -119,6 +119,11 @@ def test(self):
 
         self.assertEqual(task_type, task_head_pointee_type)
 
+        # Check whether we can find a nested type by name
+        name_type = task_type.FindNestedType("name")
+        self.assertTrue(name_type)
+        self.DebugSBType(name_type)
+
         # We'll now get the child member 'id' from 'task_head'.
         id = task_head.GetChildMemberWithName("id")
         self.DebugSBValue(id)

>From 01d3eb8a7f2d2cf5c7ad30350a19b5db04c97344 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Wed, 11 Oct 2023 07:01:09 +0300
Subject: [PATCH 03/12] Run clang-format

---
 lldb/include/lldb/Symbol/TypeSystem.h                    | 3 ++-
 lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 3 ++-
 lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h   | 3 ++-
 lldb/source/Symbol/Type.cpp                              | 3 ++-
 lldb/source/Symbol/TypeSystem.cpp                        | 3 ++-
 5 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index b503b66eb528c68..6320a3f6084251b 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -137,7 +137,8 @@ class TypeSystem : public PluginInterface,
 
   // CompilerType functions
 
-  virtual CompilerDeclContext GetCompilerDeclContextForType(const CompilerType& type);
+  virtual CompilerDeclContext
+  GetCompilerDeclContextForType(const CompilerType &type);
 
   // Tests
 #ifndef NDEBUG
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index b4bf3d3fdb20c1e..bc20720efd6d572 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2636,7 +2636,8 @@ TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
   return GetDeclContextForType(ClangUtil::GetQualType(type));
 }
 
-CompilerDeclContext TypeSystemClang::GetCompilerDeclContextForType(const CompilerType& type) {
+CompilerDeclContext
+TypeSystemClang::GetCompilerDeclContextForType(const CompilerType &type) {
   return CreateDeclContext(GetDeclContextForType(type));
 }
 
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 806ff64ef0af76b..3abbd2bb0b878f1 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -219,7 +219,8 @@ class TypeSystemClang : public TypeSystem {
 
   static clang::DeclContext *GetDeclContextForType(const CompilerType &type);
 
-  CompilerDeclContext GetCompilerDeclContextForType(const CompilerType &type) override;
+  CompilerDeclContext
+  GetCompilerDeclContextForType(const CompilerType &type) override;
 
   uint32_t GetPointerByteSize() override;
 
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index e2cf9f93f01f41d..08b79b2fdb6e19b 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -1088,7 +1088,8 @@ CompilerType TypeImpl::FindNestedType(ConstString name) {
   auto decl_context = type_system->GetCompilerDeclContextForType(m_static_type);
   llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
   TypeMap search_result;
-  symbol_file->FindTypes(name, decl_context, /*max_matches*/ 1, searched_symbol_files, search_result);
+  symbol_file->FindTypes(name, decl_context, /*max_matches*/ 1,
+                         searched_symbol_files, search_result);
   if (search_result.Empty())
     return CompilerType();
   return search_result.GetTypeAtIndex(0)->GetFullCompilerType();
diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
index ce24e312f4f35e0..874f12573eca3f0 100644
--- a/lldb/source/Symbol/TypeSystem.cpp
+++ b/lldb/source/Symbol/TypeSystem.cpp
@@ -186,7 +186,8 @@ std::optional<llvm::json::Value> TypeSystem::ReportStatistics() {
   return std::nullopt;
 }
 
-CompilerDeclContext TypeSystem::GetCompilerDeclContextForType(const CompilerType& type) {
+CompilerDeclContext
+TypeSystem::GetCompilerDeclContextForType(const CompilerType &type) {
   return CompilerDeclContext();
 }
 

>From 0ad62d9b3ae3d49195b882c0acf2b7a86c3dc4fc Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Thu, 12 Oct 2023 14:33:12 +0300
Subject: [PATCH 04/12] Handle types that doesn't have DeclContext

---
 lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 4 +++-
 lldb/source/Symbol/Type.cpp                              | 2 ++
 lldb/test/API/python_api/type/TestTypeList.py            | 4 ++++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index bc20720efd6d572..cfd09fb49d0e5e7 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2638,7 +2638,9 @@ TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
 
 CompilerDeclContext
 TypeSystemClang::GetCompilerDeclContextForType(const CompilerType &type) {
-  return CreateDeclContext(GetDeclContextForType(type));
+  if (auto *decl_context = GetDeclContextForType(type))
+    return CreateDeclContext(decl_context);
+  return CompilerDeclContext();
 }
 
 /// Aggressively desugar the provided type, skipping past various kinds of
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 08b79b2fdb6e19b..6d4d1e97ca1adf2 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -1086,6 +1086,8 @@ CompilerType TypeImpl::FindNestedType(ConstString name) {
   auto type_system = GetTypeSystem(/*prefer_dynamic*/ false);
   auto *symbol_file = type_system->GetSymbolFile();
   auto decl_context = type_system->GetCompilerDeclContextForType(m_static_type);
+  if (!decl_context.IsValid())
+    return CompilerType();
   llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
   TypeMap search_result;
   symbol_file->FindTypes(name, decl_context, /*max_matches*/ 1,
diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py
index f0054d561472f35..54afaf84a5a9c30 100644
--- a/lldb/test/API/python_api/type/TestTypeList.py
+++ b/lldb/test/API/python_api/type/TestTypeList.py
@@ -124,6 +124,10 @@ def test(self):
         self.assertTrue(name_type)
         self.DebugSBType(name_type)
 
+        task_ptr_type = task_type.GetPointerType()
+        invalid_type = task_ptr_type.FindNestedType("name")
+        self.assertFalse(invalid_type.IsValid())
+
         # We'll now get the child member 'id' from 'task_head'.
         id = task_head.GetChildMemberWithName("id")
         self.DebugSBValue(id)

>From 414a44e41864927ff4f829f8efa60afa50337633 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Thu, 12 Oct 2023 15:01:19 +0300
Subject: [PATCH 05/12] Handle empty name

---
 lldb/source/Symbol/Type.cpp                   | 2 ++
 lldb/test/API/python_api/type/TestTypeList.py | 8 +++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 6d4d1e97ca1adf2..b93dd39c3bfafd7 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -1083,6 +1083,8 @@ bool TypeImpl::GetDescription(lldb_private::Stream &strm,
 }
 
 CompilerType TypeImpl::FindNestedType(ConstString name) {
+  if (name.IsEmpty())
+    return CompilerType();
   auto type_system = GetTypeSystem(/*prefer_dynamic*/ false);
   auto *symbol_file = type_system->GetSymbolFile();
   auto decl_context = type_system->GetCompilerDeclContextForType(m_static_type);
diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py
index 54afaf84a5a9c30..3d891a01a1e2d58 100644
--- a/lldb/test/API/python_api/type/TestTypeList.py
+++ b/lldb/test/API/python_api/type/TestTypeList.py
@@ -126,7 +126,13 @@ def test(self):
 
         task_ptr_type = task_type.GetPointerType()
         invalid_type = task_ptr_type.FindNestedType("name")
-        self.assertFalse(invalid_type.IsValid())
+        self.assertFalse(invalid_type)
+
+        invalid_type = task_type.FindNestedType("")
+        self.assertFalse(invalid_type)
+
+        invalid_type = task_type.FindNestedType(None)
+        self.assertFalse(invalid_type)
 
         # We'll now get the child member 'id' from 'task_head'.
         id = task_head.GetChildMemberWithName("id")

>From 6160ffdeafde075ccec6ac3a27289204fb2bb897 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Thu, 12 Oct 2023 15:05:27 +0300
Subject: [PATCH 06/12] Add tests for enum and union

---
 lldb/test/API/python_api/type/TestTypeList.py | 8 ++++++++
 lldb/test/API/python_api/type/main.cpp        | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py
index 3d891a01a1e2d58..2d172b777cd8e76 100644
--- a/lldb/test/API/python_api/type/TestTypeList.py
+++ b/lldb/test/API/python_api/type/TestTypeList.py
@@ -124,6 +124,14 @@ def test(self):
         self.assertTrue(name_type)
         self.DebugSBType(name_type)
 
+        enum_type = task_type.FindNestedType("E")
+        self.assertTrue(enum_type)
+        self.DebugSBType(enum_type)
+
+        union_type = task_type.FindNestedType("U")
+        self.assertTrue(union_type)
+        self.DebugSBType(union_type)
+
         task_ptr_type = task_type.GetPointerType()
         invalid_type = task_ptr_type.FindNestedType("name")
         self.assertFalse(invalid_type)
diff --git a/lldb/test/API/python_api/type/main.cpp b/lldb/test/API/python_api/type/main.cpp
index b1ef625283855b5..ed50b334936e6eb 100644
--- a/lldb/test/API/python_api/type/main.cpp
+++ b/lldb/test/API/python_api/type/main.cpp
@@ -8,6 +8,8 @@ class Task {
         TASK_TYPE_1,
         TASK_TYPE_2
     } type;
+    enum E {} e;
+    union U {} u;
     // This struct is anonymous b/c it does not have a name
     // and it is not unnamed class.
     // Anonymous classes are a GNU extension.

>From 7aa9307366f552e29db3fd862940de3b661e3fbd Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Thu, 12 Oct 2023 15:11:33 +0300
Subject: [PATCH 07/12] Add a description to tests

---
 lldb/test/API/python_api/type/TestTypeList.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py
index 2d172b777cd8e76..9580416f87f4040 100644
--- a/lldb/test/API/python_api/type/TestTypeList.py
+++ b/lldb/test/API/python_api/type/TestTypeList.py
@@ -132,6 +132,8 @@ def test(self):
         self.assertTrue(union_type)
         self.DebugSBType(union_type)
 
+        # Check that FindNestedType handles types without DeclContext
+        # and other errorneous inputs
         task_ptr_type = task_type.GetPointerType()
         invalid_type = task_ptr_type.FindNestedType("name")
         self.assertFalse(invalid_type)

>From 94edf1cc076332ef2c29e2c8f9d2ed9ab567798d Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Thu, 12 Oct 2023 15:24:13 +0300
Subject: [PATCH 08/12] Run clang-format

---
 lldb/test/API/python_api/type/main.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lldb/test/API/python_api/type/main.cpp b/lldb/test/API/python_api/type/main.cpp
index ed50b334936e6eb..dd30e18cd64ca51 100644
--- a/lldb/test/API/python_api/type/main.cpp
+++ b/lldb/test/API/python_api/type/main.cpp
@@ -9,7 +9,8 @@ class Task {
         TASK_TYPE_2
     } type;
     enum E {} e;
-    union U {} u;
+    union U {
+    } u;
     // This struct is anonymous b/c it does not have a name
     // and it is not unnamed class.
     // Anonymous classes are a GNU extension.

>From 981de830e0b0f75323e252aac629dabdeeddd126 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Thu, 12 Oct 2023 21:59:12 +0300
Subject: [PATCH 09/12] Rename to FindDirectNestedType

---
 lldb/bindings/interface/SBTypeDocstrings.i    |  7 ++++---
 lldb/include/lldb/API/SBType.h                |  2 +-
 lldb/include/lldb/Symbol/Type.h               |  2 +-
 lldb/source/API/SBType.cpp                    |  4 ++--
 lldb/source/Symbol/Type.cpp                   |  2 +-
 lldb/test/API/python_api/type/TestTypeList.py | 16 ++++++++--------
 6 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/lldb/bindings/interface/SBTypeDocstrings.i b/lldb/bindings/interface/SBTypeDocstrings.i
index b4ec67da957c7d4..bebf36c5e6d1d5b 100644
--- a/lldb/bindings/interface/SBTypeDocstrings.i
+++ b/lldb/bindings/interface/SBTypeDocstrings.i
@@ -721,11 +721,12 @@ SBType supports the eq/ne operator. For example,::
 ) lldb::SBType::GetTypeFlags;
 
 %feature("docstring",
-    "Searches for a nested type that has provided name.
+    "Searches for a directly nested type that has provided name.
 
     Returns the type if it was found.
-    Returns invalid type if nothing was found."
-) lldb::SBType::FindNestedType;
+    Returns invalid type if nothing was found.
+    "
+) lldb::SBType::FindDirectNestedType;
 
 %feature("docstring",
 "Represents a list of :py:class:`SBType` s.
diff --git a/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h
index fa02197ff8f3940..9980fe1218305bb 100644
--- a/lldb/include/lldb/API/SBType.h
+++ b/lldb/include/lldb/API/SBType.h
@@ -215,7 +215,7 @@ class SBType {
   bool GetDescription(lldb::SBStream &description,
                       lldb::DescriptionLevel description_level);
 
-  lldb::SBType FindNestedType(const char *name);
+  lldb::SBType FindDirectNestedType(const char *name);
 
   lldb::SBType &operator=(const lldb::SBType &rhs);
 
diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h
index 6da4aaba401fe14..94ef6a631e39379 100644
--- a/lldb/include/lldb/Symbol/Type.h
+++ b/lldb/include/lldb/Symbol/Type.h
@@ -313,7 +313,7 @@ class TypeImpl {
   bool GetDescription(lldb_private::Stream &strm,
                       lldb::DescriptionLevel description_level);
 
-  CompilerType FindNestedType(ConstString name);
+  CompilerType FindDirectNestedType(ConstString name);
 
 private:
   bool CheckModule(lldb::ModuleSP &module_sp) const;
diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index bd8e0c16f6ea7f1..648035d2fbe6c5d 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -586,12 +586,12 @@ lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) {
   return eTemplateArgumentKindNull;
 }
 
-SBType SBType::FindNestedType(const char *name) {
+SBType SBType::FindDirectNestedType(const char *name) {
   LLDB_INSTRUMENT_VA(this, name);
 
   if (!IsValid())
     return SBType();
-  auto ret = SBType(m_opaque_sp->FindNestedType(ConstString(name)));
+  auto ret = SBType(m_opaque_sp->FindDirectNestedType(ConstString(name)));
   return ret;
 }
 
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index b93dd39c3bfafd7..8f6be9a8e6c9e0a 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -1082,7 +1082,7 @@ bool TypeImpl::GetDescription(lldb_private::Stream &strm,
   return true;
 }
 
-CompilerType TypeImpl::FindNestedType(ConstString name) {
+CompilerType TypeImpl::FindDirectNestedType(ConstString name) {
   if (name.IsEmpty())
     return CompilerType();
   auto type_system = GetTypeSystem(/*prefer_dynamic*/ false);
diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py
index 9580416f87f4040..aafb0b5908d9e47 100644
--- a/lldb/test/API/python_api/type/TestTypeList.py
+++ b/lldb/test/API/python_api/type/TestTypeList.py
@@ -119,29 +119,29 @@ def test(self):
 
         self.assertEqual(task_type, task_head_pointee_type)
 
-        # Check whether we can find a nested type by name
-        name_type = task_type.FindNestedType("name")
+        # Check whether we can find a directly nested type by name
+        name_type = task_type.FindDirectNestedType("name")
         self.assertTrue(name_type)
         self.DebugSBType(name_type)
 
-        enum_type = task_type.FindNestedType("E")
+        enum_type = task_type.FindDirectNestedType("E")
         self.assertTrue(enum_type)
         self.DebugSBType(enum_type)
 
-        union_type = task_type.FindNestedType("U")
+        union_type = task_type.FindDirectNestedType("U")
         self.assertTrue(union_type)
         self.DebugSBType(union_type)
 
-        # Check that FindNestedType handles types without DeclContext
+        # Check that FindDirectNestedType handles types without DeclContext
         # and other errorneous inputs
         task_ptr_type = task_type.GetPointerType()
-        invalid_type = task_ptr_type.FindNestedType("name")
+        invalid_type = task_ptr_type.FindDirectNestedType("name")
         self.assertFalse(invalid_type)
 
-        invalid_type = task_type.FindNestedType("")
+        invalid_type = task_type.FindDirectNestedType("")
         self.assertFalse(invalid_type)
 
-        invalid_type = task_type.FindNestedType(None)
+        invalid_type = task_type.FindDirectNestedType(None)
         self.assertFalse(invalid_type)
 
         # We'll now get the child member 'id' from 'task_head'.

>From 49d588ce51b866c9c0e02a58eb517a1ec389bdaf Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Thu, 12 Oct 2023 22:00:35 +0300
Subject: [PATCH 10/12] Add brief description for
 TypeSystem::GetCompilerDeclContextForType

---
 lldb/include/lldb/Symbol/TypeSystem.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index 6320a3f6084251b..de9087b4fcb33ac 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -137,6 +137,7 @@ class TypeSystem : public PluginInterface,
 
   // CompilerType functions
 
+  /// Returns the direct parent context of specified type
   virtual CompilerDeclContext
   GetCompilerDeclContextForType(const CompilerType &type);
 

>From 087584bfe327bf777c244b618dcf6da7c758fd65 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Thu, 12 Oct 2023 22:07:57 +0300
Subject: [PATCH 11/12] Add tests with indirectly nested types

---
 lldb/test/API/python_api/type/TestTypeList.py | 7 +++++++
 lldb/test/API/python_api/type/main.cpp        | 4 +++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py
index aafb0b5908d9e47..247e073499c7413 100644
--- a/lldb/test/API/python_api/type/TestTypeList.py
+++ b/lldb/test/API/python_api/type/TestTypeList.py
@@ -132,6 +132,13 @@ def test(self):
         self.assertTrue(union_type)
         self.DebugSBType(union_type)
 
+        # Check that we don't find indirectly nested types
+
+        self.assertTrue(enum_type.size == 1)
+
+        invalid_type = task_type.FindDirectNestedType("E2")
+        self.assertFalse(invalid_type)
+
         # Check that FindDirectNestedType handles types without DeclContext
         # and other errorneous inputs
         task_ptr_type = task_type.GetPointerType()
diff --git a/lldb/test/API/python_api/type/main.cpp b/lldb/test/API/python_api/type/main.cpp
index dd30e18cd64ca51..ca9089cacd7ffe1 100644
--- a/lldb/test/API/python_api/type/main.cpp
+++ b/lldb/test/API/python_api/type/main.cpp
@@ -8,7 +8,7 @@ class Task {
         TASK_TYPE_1,
         TASK_TYPE_2
     } type;
-    enum E {} e;
+    enum E : unsigned char {} e;
     union U {
     } u;
     // This struct is anonymous b/c it does not have a name
@@ -24,6 +24,8 @@ class Task {
     } my_type_is_nameless;
     struct name {
       int x;
+      enum E : int {} e;
+      enum E2 {} e2;
     } my_type_is_named;
     Task(int i, Task *n):
         id(i),

>From d5c067cc6ed0ea68b458bc704e56dece3ea71b6f Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Fri, 13 Oct 2023 08:56:20 +0300
Subject: [PATCH 12/12] Add a release note

---
 llvm/docs/ReleaseNotes.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index f0d4b5c5dfc7aff..0de2b7e929db383 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -186,6 +186,10 @@ Changes to LLDB
 
 * Methods in SBHostOS related to threads have had their implementations
   removed. These methods will return a value indicating failure.
+* ``SBType::FindDirectNestedType`` function is added. It's useful
+  for formatters to quickly find directly nested type when it's known
+  where to search for it, avoiding more expensive global search via
+  ``SBTarget::FindFirstType``.
 
 Changes to Sanitizers
 ---------------------



More information about the lldb-commits mailing list