mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 13:50:11 +00:00
[lldb] Add SBType::FindDirectNestedType() function (#68705)
This patch adds a `SBType::FindDirectNestedType(name)` function which performs a non-recursive search in given class for a type with specified name. The intent is to perform a fast search in debug info, so that it can be used in formatters, and let them remain responsive.
This is driven by my work on formatters for Clang and LLVM types. In particular, by [`PointerIntPairInfo::MaskAndShiftConstants`](cde9f9df79/llvm/include/llvm/ADT/PointerIntPair.h (L174C16-L174C16)
), which is required to extract pointer and integer from `PointerIntPair`.
Related Discourse thread: https://discourse.llvm.org/t/traversing-member-types-of-a-type/72452
This commit is contained in:
parent
02f67c097d
commit
93229c7bfd
@ -720,6 +720,14 @@ SBType supports the eq/ne operator. For example,::
|
|||||||
"
|
"
|
||||||
) lldb::SBType::GetTypeFlags;
|
) lldb::SBType::GetTypeFlags;
|
||||||
|
|
||||||
|
%feature("docstring",
|
||||||
|
"Searches for a directly nested type that has the provided name.
|
||||||
|
|
||||||
|
Returns the type if it was found.
|
||||||
|
Returns invalid type if nothing was found.
|
||||||
|
"
|
||||||
|
) lldb::SBType::FindDirectNestedType;
|
||||||
|
|
||||||
%feature("docstring",
|
%feature("docstring",
|
||||||
"Represents a list of :py:class:`SBType` s.
|
"Represents a list of :py:class:`SBType` s.
|
||||||
|
|
||||||
|
@ -215,6 +215,8 @@ public:
|
|||||||
bool GetDescription(lldb::SBStream &description,
|
bool GetDescription(lldb::SBStream &description,
|
||||||
lldb::DescriptionLevel description_level);
|
lldb::DescriptionLevel description_level);
|
||||||
|
|
||||||
|
lldb::SBType FindDirectNestedType(const char *name);
|
||||||
|
|
||||||
lldb::SBType &operator=(const lldb::SBType &rhs);
|
lldb::SBType &operator=(const lldb::SBType &rhs);
|
||||||
|
|
||||||
bool operator==(lldb::SBType &rhs);
|
bool operator==(lldb::SBType &rhs);
|
||||||
|
@ -304,6 +304,8 @@ public:
|
|||||||
bool GetDescription(lldb_private::Stream &strm,
|
bool GetDescription(lldb_private::Stream &strm,
|
||||||
lldb::DescriptionLevel description_level);
|
lldb::DescriptionLevel description_level);
|
||||||
|
|
||||||
|
CompilerType FindDirectNestedType(llvm::StringRef name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool CheckModule(lldb::ModuleSP &module_sp) const;
|
bool CheckModule(lldb::ModuleSP &module_sp) const;
|
||||||
bool CheckExeModule(lldb::ModuleSP &module_sp) const;
|
bool CheckExeModule(lldb::ModuleSP &module_sp) const;
|
||||||
|
@ -142,6 +142,10 @@ public:
|
|||||||
|
|
||||||
virtual lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) = 0;
|
virtual lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) = 0;
|
||||||
|
|
||||||
|
/// Returns the direct parent context of specified type
|
||||||
|
virtual CompilerDeclContext
|
||||||
|
GetCompilerDeclContextForType(const CompilerType &type);
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
/// Verify the integrity of the type to catch CompilerTypes that mix
|
/// Verify the integrity of the type to catch CompilerTypes that mix
|
||||||
|
@ -586,6 +586,14 @@ lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) {
|
|||||||
return eTemplateArgumentKindNull;
|
return eTemplateArgumentKindNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SBType SBType::FindDirectNestedType(const char *name) {
|
||||||
|
LLDB_INSTRUMENT_VA(this, name);
|
||||||
|
|
||||||
|
if (!IsValid())
|
||||||
|
return SBType();
|
||||||
|
return SBType(m_opaque_sp->FindDirectNestedType(name));
|
||||||
|
}
|
||||||
|
|
||||||
SBTypeList::SBTypeList() : m_opaque_up(new TypeListImpl()) {
|
SBTypeList::SBTypeList() : m_opaque_up(new TypeListImpl()) {
|
||||||
LLDB_INSTRUMENT_VA(this);
|
LLDB_INSTRUMENT_VA(this);
|
||||||
}
|
}
|
||||||
|
@ -2637,6 +2637,13 @@ TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
|
|||||||
return GetDeclContextForType(ClangUtil::GetQualType(type));
|
return GetDeclContextForType(ClangUtil::GetQualType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompilerDeclContext
|
||||||
|
TypeSystemClang::GetCompilerDeclContextForType(const CompilerType &type) {
|
||||||
|
if (auto *decl_context = GetDeclContextForType(type))
|
||||||
|
return CreateDeclContext(decl_context);
|
||||||
|
return CompilerDeclContext();
|
||||||
|
}
|
||||||
|
|
||||||
/// Aggressively desugar the provided type, skipping past various kinds of
|
/// Aggressively desugar the provided type, skipping past various kinds of
|
||||||
/// syntactic sugar and other constructs one typically wants to ignore.
|
/// syntactic sugar and other constructs one typically wants to ignore.
|
||||||
/// The \p mask argument allows one to skip certain kinds of simplifications,
|
/// The \p mask argument allows one to skip certain kinds of simplifications,
|
||||||
|
@ -219,6 +219,9 @@ public:
|
|||||||
|
|
||||||
static clang::DeclContext *GetDeclContextForType(const CompilerType &type);
|
static clang::DeclContext *GetDeclContextForType(const CompilerType &type);
|
||||||
|
|
||||||
|
CompilerDeclContext
|
||||||
|
GetCompilerDeclContextForType(const CompilerType &type) override;
|
||||||
|
|
||||||
uint32_t GetPointerByteSize() override;
|
uint32_t GetPointerByteSize() override;
|
||||||
|
|
||||||
clang::TranslationUnitDecl *GetTranslationUnitDecl() {
|
clang::TranslationUnitDecl *GetTranslationUnitDecl() {
|
||||||
|
@ -1040,6 +1040,23 @@ bool TypeImpl::GetDescription(lldb_private::Stream &strm,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompilerType TypeImpl::FindDirectNestedType(llvm::StringRef name) {
|
||||||
|
if (name.empty())
|
||||||
|
return CompilerType();
|
||||||
|
auto type_system = GetTypeSystem(/*prefer_dynamic*/ false);
|
||||||
|
auto *symbol_file = type_system->GetSymbolFile();
|
||||||
|
auto decl_context = type_system->GetCompilerDeclContextForType(m_static_type);
|
||||||
|
if (!decl_context.IsValid())
|
||||||
|
return CompilerType();
|
||||||
|
llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
|
||||||
|
TypeMap search_result;
|
||||||
|
symbol_file->FindTypes(ConstString(name), decl_context, /*max_matches*/ 1,
|
||||||
|
searched_symbol_files, search_result);
|
||||||
|
if (search_result.Empty())
|
||||||
|
return CompilerType();
|
||||||
|
return search_result.GetTypeAtIndex(0)->GetFullCompilerType();
|
||||||
|
}
|
||||||
|
|
||||||
bool TypeMemberFunctionImpl::IsValid() {
|
bool TypeMemberFunctionImpl::IsValid() {
|
||||||
return m_type.IsValid() && m_kind != lldb::eMemberFunctionKindUnknown;
|
return m_type.IsValid() && m_kind != lldb::eMemberFunctionKindUnknown;
|
||||||
}
|
}
|
||||||
|
@ -186,6 +186,11 @@ std::optional<llvm::json::Value> TypeSystem::ReportStatistics() {
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompilerDeclContext
|
||||||
|
TypeSystem::GetCompilerDeclContextForType(const CompilerType &type) {
|
||||||
|
return CompilerDeclContext();
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark TypeSystemMap
|
#pragma mark TypeSystemMap
|
||||||
|
|
||||||
TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {}
|
TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {}
|
||||||
|
@ -119,6 +119,37 @@ class TypeAndTypeListTestCase(TestBase):
|
|||||||
|
|
||||||
self.assertEqual(task_type, task_head_pointee_type)
|
self.assertEqual(task_type, task_head_pointee_type)
|
||||||
|
|
||||||
|
# Check whether we can find a directly nested type by name
|
||||||
|
name_type = task_type.FindDirectNestedType("name")
|
||||||
|
self.assertTrue(name_type)
|
||||||
|
self.DebugSBType(name_type)
|
||||||
|
|
||||||
|
enum_type = task_type.FindDirectNestedType("E")
|
||||||
|
self.assertTrue(enum_type)
|
||||||
|
self.DebugSBType(enum_type)
|
||||||
|
|
||||||
|
union_type = task_type.FindDirectNestedType("U")
|
||||||
|
self.assertTrue(union_type)
|
||||||
|
self.DebugSBType(union_type)
|
||||||
|
|
||||||
|
# Check that we don't find indirectly nested types
|
||||||
|
self.assertTrue(enum_type.size == 1)
|
||||||
|
|
||||||
|
invalid_type = task_type.FindDirectNestedType("E2")
|
||||||
|
self.assertFalse(invalid_type)
|
||||||
|
|
||||||
|
# Check that FindDirectNestedType handles types without DeclContext
|
||||||
|
# and other errorneous inputs
|
||||||
|
task_ptr_type = task_type.GetPointerType()
|
||||||
|
invalid_type = task_ptr_type.FindDirectNestedType("name")
|
||||||
|
self.assertFalse(invalid_type)
|
||||||
|
|
||||||
|
invalid_type = task_type.FindDirectNestedType("")
|
||||||
|
self.assertFalse(invalid_type)
|
||||||
|
|
||||||
|
invalid_type = task_type.FindDirectNestedType(None)
|
||||||
|
self.assertFalse(invalid_type)
|
||||||
|
|
||||||
# We'll now get the child member 'id' from 'task_head'.
|
# We'll now get the child member 'id' from 'task_head'.
|
||||||
id = task_head.GetChildMemberWithName("id")
|
id = task_head.GetChildMemberWithName("id")
|
||||||
self.DebugSBValue(id)
|
self.DebugSBValue(id)
|
||||||
|
@ -21,7 +21,12 @@ public:
|
|||||||
} my_type_is_nameless;
|
} my_type_is_nameless;
|
||||||
struct name {
|
struct name {
|
||||||
int x;
|
int x;
|
||||||
|
enum E : int {} e;
|
||||||
|
enum E2 {} e2;
|
||||||
} my_type_is_named;
|
} my_type_is_named;
|
||||||
|
enum E : unsigned char {} e;
|
||||||
|
union U {
|
||||||
|
} u;
|
||||||
Task(int i, Task *n):
|
Task(int i, Task *n):
|
||||||
id(i),
|
id(i),
|
||||||
next(n),
|
next(n),
|
||||||
|
@ -191,6 +191,10 @@ Changes to LLDB
|
|||||||
|
|
||||||
* Methods in SBHostOS related to threads have had their implementations
|
* Methods in SBHostOS related to threads have had their implementations
|
||||||
removed. These methods will return a value indicating failure.
|
removed. These methods will return a value indicating failure.
|
||||||
|
* ``SBType::FindDirectNestedType`` function is added. It's useful
|
||||||
|
for formatters to quickly find directly nested type when it's known
|
||||||
|
where to search for it, avoiding more expensive global search via
|
||||||
|
``SBTarget::FindFirstType``.
|
||||||
|
|
||||||
Changes to Sanitizers
|
Changes to Sanitizers
|
||||||
---------------------
|
---------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user