<rdar://problem/12493007>
authorGreg Clayton <gclayton@apple.com>
Tue, 23 Oct 2012 01:50:10 +0000 (01:50 +0000)
committerGreg Clayton <gclayton@apple.com>
Tue, 23 Oct 2012 01:50:10 +0000 (01:50 +0000)
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
lldb/include/lldb/Core/ValueObject.h
lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
lldb/scripts/Python/interface/SBValue.i
lldb/source/API/SBValue.cpp
lldb/source/Core/ValueObject.cpp
lldb/source/Core/ValueObjectSyntheticFilter.cpp

index 2c02a7c..09e0904 100644 (file)
@@ -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 ();
 
index cbb6234..9ca60e5 100644 (file)
@@ -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<ValueObject> ValueObjectManager;
     
index dbe9b83..eadfc69 100644 (file)
@@ -39,6 +39,9 @@ public:
     virtual ConstString
     GetTypeName();
 
+    virtual bool
+    MightHaveChildren();
+
     virtual uint32_t
     CalculateNumChildren();
 
index 00d9b56..1535c77 100644 (file)
@@ -302,6 +302,9 @@ public:
     lldb::SBDeclaration
     GetDeclaration ();
     
+    bool
+    MightHaveChildren ();
+
     uint32_t
     GetNumChildren ();
 
index 318029f..9e80310 100644 (file)
@@ -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 ()
 {
index b5b55c9..41c7dbe 100644 (file)
@@ -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)
 {
index 284515a..fe8e90c 100644 (file)
@@ -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 ()
 {