llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) <details> <summary>Changes</summary> 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). --- Full diff: https://github.com/llvm/llvm-project/pull/89183.diff 5 Files Affected: - (modified) lldb/include/lldb/Symbol/TypeSystem.h (+7) - (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+30) - (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h (+4) - (modified) lldb/source/Symbol/Type.cpp (+1-14) - (modified) lldb/test/API/python_api/type/TestTypeList.py (+19-16) ``````````diff 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") `````````` </details> https://github.com/llvm/llvm-project/pull/89183 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits