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

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).

>From d8e6fdff0df7b1a2e9242d747831966c5db03e44 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pa...@labath.sk>
Date: Thu, 18 Apr 2024 07:34:45 +0000
Subject: [PATCH] [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        |  4 +++
 lldb/source/Symbol/Type.cpp                   | 15 +-------
 lldb/test/API/python_api/type/TestTypeList.py | 35 ++++++++++---------
 5 files changed, 61 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..cfe5327e14f823 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -897,6 +897,10 @@ 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..5c49c4726157fb 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -1177,20 +1177,7 @@ 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..b27842eb3be87a 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,10 @@ 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")

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to