From 4a792072ceea00696c9bbce3de74c348cce608b9 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Tue, 23 Oct 2012 01:50:10 +0000 Subject: [PATCH] Added a new API call to help efficiently determine if a SBValue could have children: bool SBValue::MightHaveChildren (); This is inteneded to be used bui GUI programs that need to show if a SBValue needs a disclosure triangle when displaying a hierarchical type in a tree view without having to complete the type (by calling SBValue::GetNumChildren()) as completing the type is expensive. llvm-svn: 166460 --- lldb/include/lldb/API/SBValue.h | 19 +++++++++++++++++ lldb/include/lldb/Core/ValueObject.h | 19 +++++++++++++++++ .../include/lldb/Core/ValueObjectSyntheticFilter.h | 3 +++ lldb/scripts/Python/interface/SBValue.i | 3 +++ lldb/source/API/SBValue.cpp | 14 +++++++++++++ lldb/source/Core/ValueObject.cpp | 24 ++++++++++++++++++++++ lldb/source/Core/ValueObjectSyntheticFilter.cpp | 8 ++++++++ 7 files changed, 90 insertions(+) diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 2c02a7c9..09e0904 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -293,6 +293,25 @@ public: lldb::SBDeclaration GetDeclaration (); + //------------------------------------------------------------------ + /// Find out if a SBValue might have children. + /// + /// This call is much more efficient than GetNumChildren() as it + /// doesn't need to complete the underlying type. This is designed + /// to be used in a UI environment in order to detect if the + /// disclosure triangle should be displayed or not. + /// + /// This function returns true for class, union, structure, + /// pointers, references, arrays and more. Again, it does so without + /// doing any expensive type completion. + /// + /// @return + /// Returns \b true if the SBValue might have children, or \b + /// false otherwise. + //------------------------------------------------------------------ + bool + MightHaveChildren (); + uint32_t GetNumChildren (); diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index cbb6234..9ca60e5 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -1071,6 +1071,25 @@ public: m_did_calculate_complete_objc_class_type = true; } + //------------------------------------------------------------------ + /// Find out if a SBValue might have children. + /// + /// This call is much more efficient than CalculateNumChildren() as + /// it doesn't need to complete the underlying type. This is designed + /// to be used in a UI environment in order to detect if the + /// disclosure triangle should be displayed or not. + /// + /// This function returns true for class, union, structure, + /// pointers, references, arrays and more. Again, it does so without + /// doing any expensive type completion. + /// + /// @return + /// Returns \b true if the SBValue might have children, or \b + /// false otherwise. + //------------------------------------------------------------------ + virtual bool + MightHaveChildren(); + protected: typedef ClusterManager ValueObjectManager; diff --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index dbe9b83..eadfc69 100644 --- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -39,6 +39,9 @@ public: virtual ConstString GetTypeName(); + virtual bool + MightHaveChildren(); + virtual uint32_t CalculateNumChildren(); diff --git a/lldb/scripts/Python/interface/SBValue.i b/lldb/scripts/Python/interface/SBValue.i index 00d9b56..1535c77 100644 --- a/lldb/scripts/Python/interface/SBValue.i +++ b/lldb/scripts/Python/interface/SBValue.i @@ -302,6 +302,9 @@ public: lldb::SBDeclaration GetDeclaration (); + bool + MightHaveChildren (); + uint32_t GetNumChildren (); diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 318029f..9e80310 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -1354,6 +1354,20 @@ SBValue::GetValueAsUnsigned(uint64_t fail_value) return fail_value; } +bool +SBValue::MightHaveChildren () +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool has_children = false; + lldb::ValueObjectSP value_sp(GetSP()); + if (value_sp) + has_children = value_sp->MightHaveChildren(); + + if (log) + log->Printf ("SBValue(%p)::HasChildren() => %i", value_sp.get(), has_children); + return has_children; +} + uint32_t SBValue::GetNumChildren () { diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index b5b55c9..41c7dbe 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -597,6 +597,30 @@ ValueObject::GetNumChildren () } return m_children.GetChildrenCount(); } + +bool +ValueObject::MightHaveChildren() +{ + bool has_children; + clang_type_t clang_type = GetClangType(); + if (clang_type) + { + const uint32_t type_info = ClangASTContext::GetTypeInfo (clang_type, + GetClangAST(), + NULL); + if (type_info & (ClangASTContext::eTypeHasChildren | + ClangASTContext::eTypeIsPointer | + ClangASTContext::eTypeIsReference)) + has_children = true; + } + else + { + has_children = GetNumChildren () > 0; + } + return has_children; +} + +// Should only be called by ValueObject::GetNumChildren() void ValueObject::SetNumChildren (uint32_t num_children) { diff --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp index 284515a..fe8e90cf 100644 --- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -96,6 +96,14 @@ ValueObjectSynthetic::CalculateNumChildren() return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren()); } +bool +ValueObjectSynthetic::MightHaveChildren() +{ + // TODO: make this more efficient by adding API calls to calculate this efficiently + return GetNumChildren () > 0; +} + + clang::ASTContext * ValueObjectSynthetic::GetClangASTImpl () { -- 2.7.4