Skip to content

Commit 80ba4f2

Browse files
committed
[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).
1 parent 3c721b9 commit 80ba4f2

File tree

5 files changed

+63
-30
lines changed

5 files changed

+63
-30
lines changed

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/Type.cpp

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,20 +1177,8 @@ CompilerType TypeImpl::FindDirectNestedType(llvm::StringRef name) {
11771177
if (name.empty())
11781178
return CompilerType();
11791179
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();
1180+
return type_system->GetDirectNestedTypeWithName(
1181+
m_static_type.GetOpaqueQualType(), name);
11941182
}
11951183

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