[Lldb-commits] [lldb] [lldb] Make SBType::FindDirectNestedType work with expression ASTs (PR #89183)

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Fri Apr 19 05:13:52 PDT 2024


https://github.com/labath updated https://github.com/llvm/llvm-project/pull/89183

>From 80ba4f24cdfe8b5f2aa44a016ea69ad08f56d558 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Thu, 18 Apr 2024 07:34:45 +0000
Subject: [PATCH 1/2] [lldb] Make SBType::FindDirectNestedType work with
 expression ASTs

The types we get out of expressions will not have an associated symbol
file, so the current method of looking up the type will fail. Instead, I
plumb the query through the TypeSystem class. This correctly finds the
type in both cases (importing it into the expression AST if needed). I
haven't measured, but it should also be more efficient than doing a type
lookup (at least, after the type has already been found once).
---
 lldb/include/lldb/Symbol/TypeSystem.h         |  7 ++++
 .../TypeSystem/Clang/TypeSystemClang.cpp      | 30 +++++++++++++++
 .../TypeSystem/Clang/TypeSystemClang.h        |  3 ++
 lldb/source/Symbol/Type.cpp                   | 16 +-------
 lldb/test/API/python_api/type/TestTypeList.py | 37 +++++++++++--------
 5 files changed, 63 insertions(+), 30 deletions(-)

diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index f647fcbf1636ea..3a927d313b823d 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -28,6 +28,7 @@
 #include "lldb/Symbol/CompilerDeclContext.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/lldb-private.h"
+#include "lldb/lldb-types.h"
 
 class PDBASTParser;
 
@@ -363,6 +364,12 @@ class TypeSystem : public PluginInterface,
       lldb::opaque_compiler_type_t type, llvm::StringRef name,
       bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) = 0;
 
+  virtual CompilerType
+  GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
+                              llvm::StringRef name) {
+    return CompilerType();
+  }
+
   virtual bool IsTemplateType(lldb::opaque_compiler_type_t type);
 
   virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index be0ddb06f82c18..2621f682011b41 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -6997,6 +6997,36 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
   return UINT32_MAX;
 }
 
+CompilerType
+TypeSystemClang::GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
+                                             llvm::StringRef name) {
+  if (!type || name.empty())
+    return CompilerType();
+
+  clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+  switch (type_class) {
+  case clang::Type::Record: {
+    if (!GetCompleteType(type))
+      return CompilerType();
+    const clang::RecordType *record_type =
+        llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+    const clang::RecordDecl *record_decl = record_type->getDecl();
+
+    clang::DeclarationName decl_name(&getASTContext().Idents.get(name));
+    for (NamedDecl *decl : record_decl->lookup(decl_name)) {
+      if (auto *tag_decl = dyn_cast<clang::TagDecl>(decl))
+        return GetType(getASTContext().getTagDeclType(tag_decl));
+    }
+    break;
+  }
+  default:
+    break;
+  }
+  return CompilerType();
+}
+
 bool TypeSystemClang::IsTemplateType(lldb::opaque_compiler_type_t type) {
   if (!type)
     return false;
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 05c303baa41640..68b82e9688f12b 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -897,6 +897,9 @@ class TypeSystemClang : public TypeSystem {
                                 bool omit_empty_base_classes,
                                 std::vector<uint32_t> &child_indexes) override;
 
+  CompilerType GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
+                                           llvm::StringRef name) override;
+
   bool IsTemplateType(lldb::opaque_compiler_type_t type) override;
 
   size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 44a24d7178f562..d9894ac355c6f0 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -1177,20 +1177,8 @@ CompilerType TypeImpl::FindDirectNestedType(llvm::StringRef name) {
   if (name.empty())
     return CompilerType();
   auto type_system = GetTypeSystem(/*prefer_dynamic*/ false);
-  auto *symbol_file = type_system->GetSymbolFile();
-  if (!symbol_file)
-    return CompilerType();
-  auto decl_context = type_system->GetCompilerDeclContextForType(m_static_type);
-  if (!decl_context.IsValid())
-    return CompilerType();
-  TypeQuery query(decl_context, ConstString(name),
-                  TypeQueryOptions::e_find_one);
-  TypeResults results;
-  symbol_file->FindTypes(query, results);
-  TypeSP type_sp = results.GetFirstType();
-  if (type_sp)
-    return type_sp->GetFullCompilerType();
-  return CompilerType();
+  return type_system->GetDirectNestedTypeWithName(
+      m_static_type.GetOpaqueQualType(), name);
 }
 
 bool TypeMemberFunctionImpl::IsValid() {
diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py
index eba5e17355c3f8..09c1dee80ef6c4 100644
--- a/lldb/test/API/python_api/type/TestTypeList.py
+++ b/lldb/test/API/python_api/type/TestTypeList.py
@@ -18,6 +18,21 @@ def setUp(self):
         self.source = "main.cpp"
         self.line = line_number(self.source, "// Break at this line")
 
+    def _find_nested_type_in_Task_pointer(self, pointer_type):
+        self.assertTrue(pointer_type)
+        self.DebugSBType(pointer_type)
+        pointer_info_type = pointer_type.template_args[1]
+        self.assertTrue(pointer_info_type)
+        self.DebugSBType(pointer_info_type)
+
+        pointer_masks1_type = pointer_info_type.FindDirectNestedType("Masks1")
+        self.assertTrue(pointer_masks1_type)
+        self.DebugSBType(pointer_masks1_type)
+
+        pointer_masks2_type = pointer_info_type.FindDirectNestedType("Masks2")
+        self.assertTrue(pointer_masks2_type)
+        self.DebugSBType(pointer_masks2_type)
+
     @skipIf(compiler="clang", compiler_version=["<", "17.0"])
     def test(self):
         """Exercise SBType and SBTypeList API."""
@@ -151,22 +166,12 @@ def test(self):
         invalid_type = task_type.FindDirectNestedType(None)
         self.assertFalse(invalid_type)
 
-        # Check that FindDirectNestedType works with types from AST
-        pointer = frame0.FindVariable("pointer")
-        pointer_type = pointer.GetType()
-        self.assertTrue(pointer_type)
-        self.DebugSBType(pointer_type)
-        pointer_info_type = pointer_type.template_args[1]
-        self.assertTrue(pointer_info_type)
-        self.DebugSBType(pointer_info_type)
-
-        pointer_masks1_type = pointer_info_type.FindDirectNestedType("Masks1")
-        self.assertTrue(pointer_masks1_type)
-        self.DebugSBType(pointer_masks1_type)
-
-        pointer_masks2_type = pointer_info_type.FindDirectNestedType("Masks2")
-        self.assertTrue(pointer_masks2_type)
-        self.DebugSBType(pointer_masks2_type)
+        # Check that FindDirectNestedType works with types from module and
+        # expression ASTs.
+        self._find_nested_type_in_Task_pointer(frame0.FindVariable("pointer").GetType())
+        self._find_nested_type_in_Task_pointer(
+            frame0.EvaluateExpression("pointer").GetType()
+        )
 
         # We'll now get the child member 'id' from 'task_head'.
         id = task_head.GetChildMemberWithName("id")

>From e30ad3ee99470bfaae6bc4dc1ac3f85ba6c68ece Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Fri, 19 Apr 2024 12:08:33 +0000
Subject: [PATCH 2/2] Add CompilerType wrapper for GetDirectNestedTypeWithName

---
 lldb/include/lldb/Symbol/CompilerType.h | 2 ++
 lldb/source/Symbol/CompilerType.cpp     | 9 +++++++++
 lldb/source/Symbol/Type.cpp             | 4 +---
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h
index c1dce4ccbf79c2..b71c531f21633a 100644
--- a/lldb/include/lldb/Symbol/CompilerType.h
+++ b/lldb/include/lldb/Symbol/CompilerType.h
@@ -447,6 +447,8 @@ class CompilerType {
                                 bool omit_empty_base_classes,
                                 std::vector<uint32_t> &child_indexes) const;
 
+  CompilerType GetDirectNestedTypeWithName(llvm::StringRef name) const;
+
   /// Return the number of template arguments the type has.
   /// If expand_pack is true, then variadic argument packs are automatically
   /// expanded to their supplied arguments. If it is false an argument pack
diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index 8e4c3c761f784e..96e74b890d2d90 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -931,6 +931,15 @@ size_t CompilerType::GetIndexOfChildMemberWithName(
   return 0;
 }
 
+CompilerType
+CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
+  if (IsValid() && !name.empty()) {
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetDirectNestedTypeWithName(m_type, name);
+  }
+  return CompilerType();
+}
+
 size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
   if (IsValid()) {
     if (auto type_system_sp = GetTypeSystem())
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index d9894ac355c6f0..e043c83f294261 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -1176,9 +1176,7 @@ bool TypeImpl::GetDescription(lldb_private::Stream &strm,
 CompilerType TypeImpl::FindDirectNestedType(llvm::StringRef name) {
   if (name.empty())
     return CompilerType();
-  auto type_system = GetTypeSystem(/*prefer_dynamic*/ false);
-  return type_system->GetDirectNestedTypeWithName(
-      m_static_type.GetOpaqueQualType(), name);
+  return GetCompilerType(/*prefer_dynamic=*/false).GetDirectNestedTypeWithName(name);
 }
 
 bool TypeMemberFunctionImpl::IsValid() {



More information about the lldb-commits mailing list