Skip to content

Commit 8008361

Browse files
labathaniplcc
authored andcommitted
[lldb] Make SBType::FindDirectNestedType work with expression ASTs (llvm#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).
1 parent abdf644 commit 8008361

File tree

7 files changed

+74
-31
lines changed

7 files changed

+74
-31
lines changed

lldb/include/lldb/Symbol/CompilerType.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ class CompilerType {
447447
bool omit_empty_base_classes,
448448
std::vector<uint32_t> &child_indexes) const;
449449

450+
CompilerType GetDirectNestedTypeWithName(llvm::StringRef name) const;
451+
450452
/// Return the number of template arguments the type has.
451453
/// If expand_pack is true, then variadic argument packs are automatically
452454
/// expanded to their supplied arguments. If it is false an argument pack

lldb/include/lldb/Symbol/TypeSystem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "lldb/Symbol/CompilerDeclContext.h"
2929
#include "lldb/Symbol/Type.h"
3030
#include "lldb/lldb-private.h"
31+
#include "lldb/lldb-types.h"
3132

3233
class PDBASTParser;
3334

@@ -363,6 +364,12 @@ class TypeSystem : public PluginInterface,
363364
lldb::opaque_compiler_type_t type, llvm::StringRef name,
364365
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) = 0;
365366

367+
virtual CompilerType
368+
GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
369+
llvm::StringRef name) {
370+
return CompilerType();
371+
}
372+
366373
virtual bool IsTemplateType(lldb::opaque_compiler_type_t type);
367374

368375
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6997,6 +6997,36 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
69976997
return UINT32_MAX;
69986998
}
69996999

7000+
CompilerType
7001+
TypeSystemClang::GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
7002+
llvm::StringRef name) {
7003+
if (!type || name.empty())
7004+
return CompilerType();
7005+
7006+
clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
7007+
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7008+
7009+
switch (type_class) {
7010+
case clang::Type::Record: {
7011+
if (!GetCompleteType(type))
7012+
return CompilerType();
7013+
const clang::RecordType *record_type =
7014+
llvm::cast<clang::RecordType>(qual_type.getTypePtr());
7015+
const clang::RecordDecl *record_decl = record_type->getDecl();
7016+
7017+
clang::DeclarationName decl_name(&getASTContext().Idents.get(name));
7018+
for (NamedDecl *decl : record_decl->lookup(decl_name)) {
7019+
if (auto *tag_decl = dyn_cast<clang::TagDecl>(decl))
7020+
return GetType(getASTContext().getTagDeclType(tag_decl));
7021+
}
7022+
break;
7023+
}
7024+
default:
7025+
break;
7026+
}
7027+
return CompilerType();
7028+
}
7029+
70007030
bool TypeSystemClang::IsTemplateType(lldb::opaque_compiler_type_t type) {
70017031
if (!type)
70027032
return false;

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,9 @@ class TypeSystemClang : public TypeSystem {
897897
bool omit_empty_base_classes,
898898
std::vector<uint32_t> &child_indexes) override;
899899

900+
CompilerType GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
901+
llvm::StringRef name) override;
902+
900903
bool IsTemplateType(lldb::opaque_compiler_type_t type) override;
901904

902905
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,

lldb/source/Symbol/CompilerType.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,15 @@ size_t CompilerType::GetIndexOfChildMemberWithName(
931931
return 0;
932932
}
933933

934+
CompilerType
935+
CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
936+
if (IsValid() && !name.empty()) {
937+
if (auto type_system_sp = GetTypeSystem())
938+
return type_system_sp->GetDirectNestedTypeWithName(m_type, name);
939+
}
940+
return CompilerType();
941+
}
942+
934943
size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
935944
if (IsValid()) {
936945
if (auto type_system_sp = GetTypeSystem())

lldb/source/Symbol/Type.cpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,21 +1176,8 @@ bool TypeImpl::GetDescription(lldb_private::Stream &strm,
11761176
CompilerType TypeImpl::FindDirectNestedType(llvm::StringRef name) {
11771177
if (name.empty())
11781178
return CompilerType();
1179-
auto type_system = GetTypeSystem(/*prefer_dynamic*/ false);
1180-
auto *symbol_file = type_system->GetSymbolFile();
1181-
if (!symbol_file)
1182-
return CompilerType();
1183-
auto decl_context = type_system->GetCompilerDeclContextForType(m_static_type);
1184-
if (!decl_context.IsValid())
1185-
return CompilerType();
1186-
TypeQuery query(decl_context, ConstString(name),
1187-
TypeQueryOptions::e_find_one);
1188-
TypeResults results;
1189-
symbol_file->FindTypes(query, results);
1190-
TypeSP type_sp = results.GetFirstType();
1191-
if (type_sp)
1192-
return type_sp->GetFullCompilerType();
1193-
return CompilerType();
1179+
return GetCompilerType(/*prefer_dynamic=*/false)
1180+
.GetDirectNestedTypeWithName(name);
11941181
}
11951182

11961183
bool TypeMemberFunctionImpl::IsValid() {

lldb/test/API/python_api/type/TestTypeList.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ def setUp(self):
1818
self.source = "main.cpp"
1919
self.line = line_number(self.source, "// Break at this line")
2020

21+
def _find_nested_type_in_Task_pointer(self, pointer_type):
22+
self.assertTrue(pointer_type)
23+
self.DebugSBType(pointer_type)
24+
pointer_info_type = pointer_type.template_args[1]
25+
self.assertTrue(pointer_info_type)
26+
self.DebugSBType(pointer_info_type)
27+
28+
pointer_masks1_type = pointer_info_type.FindDirectNestedType("Masks1")
29+
self.assertTrue(pointer_masks1_type)
30+
self.DebugSBType(pointer_masks1_type)
31+
32+
pointer_masks2_type = pointer_info_type.FindDirectNestedType("Masks2")
33+
self.assertTrue(pointer_masks2_type)
34+
self.DebugSBType(pointer_masks2_type)
35+
2136
@skipIf(compiler="clang", compiler_version=["<", "17.0"])
2237
def test(self):
2338
"""Exercise SBType and SBTypeList API."""
@@ -151,22 +166,12 @@ def test(self):
151166
invalid_type = task_type.FindDirectNestedType(None)
152167
self.assertFalse(invalid_type)
153168

154-
# Check that FindDirectNestedType works with types from AST
155-
pointer = frame0.FindVariable("pointer")
156-
pointer_type = pointer.GetType()
157-
self.assertTrue(pointer_type)
158-
self.DebugSBType(pointer_type)
159-
pointer_info_type = pointer_type.template_args[1]
160-
self.assertTrue(pointer_info_type)
161-
self.DebugSBType(pointer_info_type)
162-
163-
pointer_masks1_type = pointer_info_type.FindDirectNestedType("Masks1")
164-
self.assertTrue(pointer_masks1_type)
165-
self.DebugSBType(pointer_masks1_type)
166-
167-
pointer_masks2_type = pointer_info_type.FindDirectNestedType("Masks2")
168-
self.assertTrue(pointer_masks2_type)
169-
self.DebugSBType(pointer_masks2_type)
169+
# Check that FindDirectNestedType works with types from module and
170+
# expression ASTs.
171+
self._find_nested_type_in_Task_pointer(frame0.FindVariable("pointer").GetType())
172+
self._find_nested_type_in_Task_pointer(
173+
frame0.EvaluateExpression("pointer").GetType()
174+
)
170175

171176
# We'll now get the child member 'id' from 'task_head'.
172177
id = task_head.GetChildMemberWithName("id")

0 commit comments

Comments
 (0)