Skip to content

[lldb] Make SBType::FindDirectNestedType work with expression ASTs #89183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lldb/include/lldb/Symbol/CompilerType.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions lldb/include/lldb/Symbol/TypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down
30 changes: 30 additions & 0 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 9 additions & 0 deletions lldb/source/Symbol/CompilerType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
17 changes: 2 additions & 15 deletions lldb/source/Symbol/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1176,21 +1176,8 @@ 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);
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 GetCompilerType(/*prefer_dynamic=*/false)
.GetDirectNestedTypeWithName(name);
}

bool TypeMemberFunctionImpl::IsValid() {
Expand Down
37 changes: 21 additions & 16 deletions lldb/test/API/python_api/type/TestTypeList.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down Expand Up @@ -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")
Expand Down