From 9ac7a6c51f8643e8a44af41efca0c8c148315bc5 Mon Sep 17 00:00:00 2001 From: Siva Chandra Date: Wed, 21 Oct 2015 19:28:08 +0000 Subject: [PATCH] [SBValue] Add a method GetNumChildren(uint32_t max) Summary: Along with this, support for an optional argument to the "num_children" method of a Python synthetic child provider has also been added. These have been added with the following use case in mind: Synthetic child providers currently have a method "has_children" and "num_children". While the former is good enough to know if there are children, it does not give any insight into how many children there are. Though the latter serves this purpose, calculating the number for children of a data structure could be an O(N) operation if the data structure has N children. The new method added in this change provide a middle ground. One can call GetNumChildren(K) to know if a child exists at an index K which can be as large as the callers tolerance can be. If the caller wants to know about children beyond K, it can make an other call with 2K. If the synthetic child provider maintains state about it counting till K previosly, then the next call is only an O(K) operation. Infact, all calls made progressively with steps of K will be O(K) operations. Reviewers: vharron, clayborg, granata.enrico Subscribers: labath, lldb-commits Differential Revision: http://reviews.llvm.org/D13778 llvm-svn: 250930 --- lldb/include/lldb/API/SBValue.h | 3 ++ lldb/include/lldb/Core/ValueObject.h | 4 +-- lldb/include/lldb/Core/ValueObjectCast.h | 2 +- lldb/include/lldb/Core/ValueObjectChild.h | 2 +- .../lldb/Core/ValueObjectConstResult.h | 2 +- .../lldb/Core/ValueObjectDynamicValue.h | 2 +- lldb/include/lldb/Core/ValueObjectMemory.h | 2 +- lldb/include/lldb/Core/ValueObjectRegister.h | 6 ++-- .../lldb/Core/ValueObjectSyntheticFilter.h | 2 +- lldb/include/lldb/Core/ValueObjectVariable.h | 2 +- .../lldb/DataFormatters/TypeSynthetic.h | 20 ++++++++--- .../lldb/Interpreter/ScriptInterpreter.h | 2 +- lldb/scripts/Python/python-wrapper.swig | 33 +++++++++++++++---- lldb/scripts/interface/SBValue.i | 17 +++++++++- lldb/source/API/SBValue.cpp | 13 +++++--- lldb/source/API/SystemInitializerFull.cpp | 2 +- lldb/source/Core/ValueObject.cpp | 14 +++++++- lldb/source/Core/ValueObjectCast.cpp | 5 +-- lldb/source/Core/ValueObjectChild.cpp | 5 +-- lldb/source/Core/ValueObjectConstResult.cpp | 5 +-- lldb/source/Core/ValueObjectDynamicValue.cpp | 9 +++-- lldb/source/Core/ValueObjectMemory.cpp | 11 +++++-- lldb/source/Core/ValueObjectRegister.cpp | 17 ++++++---- .../Core/ValueObjectSyntheticFilter.cpp | 14 +++++--- lldb/source/Core/ValueObjectVariable.cpp | 5 +-- lldb/source/DataFormatters/TypeSynthetic.cpp | 10 +++++- .../Python/ScriptInterpreterPython.cpp | 4 +-- .../Python/ScriptInterpreterPython.h | 4 +-- .../TestDataFormatterSynthVal.py | 7 ++++ .../data-formatter-synthval/main.cpp | 7 ++++ .../myIntSynthProvider.py | 19 +++++++++++ 31 files changed, 189 insertions(+), 61 deletions(-) diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index cbcfcb69263d..232546a0c312 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -330,6 +330,9 @@ public: uint32_t GetNumChildren (); + uint32_t + GetNumChildren (uint32_t max); + void * GetOpaqueType(); diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index 0f97a5c9351e..a95052268ffb 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -595,7 +595,7 @@ public: GetIndexOfChildWithName (const ConstString &name); size_t - GetNumChildren (); + GetNumChildren (uint32_t max=UINT32_MAX); const Value & GetValue() const; @@ -1204,7 +1204,7 @@ protected: // Should only be called by ValueObject::GetNumChildren() virtual size_t - CalculateNumChildren() = 0; + CalculateNumChildren(uint32_t max=UINT32_MAX) = 0; void SetNumChildren (size_t num_children); diff --git a/lldb/include/lldb/Core/ValueObjectCast.h b/lldb/include/lldb/Core/ValueObjectCast.h index 8bbc9da6fb48..215a56349f22 100644 --- a/lldb/include/lldb/Core/ValueObjectCast.h +++ b/lldb/include/lldb/Core/ValueObjectCast.h @@ -35,7 +35,7 @@ public: GetByteSize() override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; lldb::ValueType GetValueType() const override; diff --git a/lldb/include/lldb/Core/ValueObjectChild.h b/lldb/include/lldb/Core/ValueObjectChild.h index da89534aa9c9..d22eee5ae3f6 100644 --- a/lldb/include/lldb/Core/ValueObjectChild.h +++ b/lldb/include/lldb/Core/ValueObjectChild.h @@ -56,7 +56,7 @@ public: GetValueType() const override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; ConstString GetTypeName() override; diff --git a/lldb/include/lldb/Core/ValueObjectConstResult.h b/lldb/include/lldb/Core/ValueObjectConstResult.h index 4848149e6a6d..2a81676b6b31 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -76,7 +76,7 @@ public: GetValueType() const override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; ConstString GetTypeName() override; diff --git a/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/lldb/include/lldb/Core/ValueObjectDynamicValue.h index 925f8ef87870..bb4738e99e6c 100644 --- a/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -41,7 +41,7 @@ public: GetDisplayTypeName() override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; lldb::ValueType GetValueType() const override; diff --git a/lldb/include/lldb/Core/ValueObjectMemory.h b/lldb/include/lldb/Core/ValueObjectMemory.h index 7539de1b6e7b..0e12fc7e3f28 100644 --- a/lldb/include/lldb/Core/ValueObjectMemory.h +++ b/lldb/include/lldb/Core/ValueObjectMemory.h @@ -50,7 +50,7 @@ public: GetDisplayTypeName() override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; lldb::ValueType GetValueType() const override; diff --git a/lldb/include/lldb/Core/ValueObjectRegister.h b/lldb/include/lldb/Core/ValueObjectRegister.h index 4e984bb5efe8..ac76f9e4280b 100644 --- a/lldb/include/lldb/Core/ValueObjectRegister.h +++ b/lldb/include/lldb/Core/ValueObjectRegister.h @@ -48,7 +48,7 @@ public: GetDisplayTypeName() override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; ValueObject * CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index) override; @@ -94,7 +94,7 @@ public: GetQualifiedTypeName() override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; ValueObject * CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index) override; @@ -148,7 +148,7 @@ public: GetTypeName() override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; bool SetValueFromCString(const char *value_str, Error& error) override; diff --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index 33aa59a51687..4cdbf6e4d41a 100644 --- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -49,7 +49,7 @@ public: MightHaveChildren() override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; lldb::ValueType GetValueType() const override; diff --git a/lldb/include/lldb/Core/ValueObjectVariable.h b/lldb/include/lldb/Core/ValueObjectVariable.h index af13a1d945c4..3e472db41cff 100644 --- a/lldb/include/lldb/Core/ValueObjectVariable.h +++ b/lldb/include/lldb/Core/ValueObjectVariable.h @@ -43,7 +43,7 @@ public: GetDisplayTypeName() override; size_t - CalculateNumChildren() override; + CalculateNumChildren(uint32_t max) override; lldb::ValueType GetValueType() const override; diff --git a/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/lldb/include/lldb/DataFormatters/TypeSynthetic.h index b452e2220b1e..c2e16897efcb 100644 --- a/lldb/include/lldb/DataFormatters/TypeSynthetic.h +++ b/lldb/include/lldb/DataFormatters/TypeSynthetic.h @@ -56,13 +56,20 @@ namespace lldb_private { ~SyntheticChildrenFrontEnd () { } - + virtual size_t CalculateNumChildren () = 0; + + virtual size_t + CalculateNumChildren (uint32_t max) + { + auto count = CalculateNumChildren (); + return count <= max ? count : max; + } virtual lldb::ValueObjectSP GetChildAtIndex (size_t idx) = 0; - + virtual size_t GetIndexOfChildWithName (const ConstString &name) = 0; @@ -454,7 +461,7 @@ namespace lldb_private { return lldb::ValueObjectSP(); return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true); } - + bool Update() override { return false; } @@ -589,13 +596,16 @@ namespace lldb_private { IsValid (); ~FrontEnd() override; - + size_t CalculateNumChildren() override; + + size_t + CalculateNumChildren(uint32_t max) override; lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; - + bool Update() override; diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 8a67807c810e..5904ca7f4df1 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -349,7 +349,7 @@ public: } virtual size_t - CalculateNumChildren(const StructuredData::ObjectSP &implementor) + CalculateNumChildren(const StructuredData::ObjectSP &implementor, uint32_t max) { return 0; } diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig index a4d982609cb4..a2ea16abdab5 100644 --- a/lldb/scripts/Python/python-wrapper.swig +++ b/lldb/scripts/Python/python-wrapper.swig @@ -113,9 +113,18 @@ public: argc GetNumArguments () { - if (m_callable && PyFunction_Check(m_callable)) + PyObject *py_func_obj = NULL; + if (m_callable) { - PyCodeObject* code = (PyCodeObject*)PyFunction_GET_CODE(m_callable); + if (PyMethod_Check(m_callable)) + py_func_obj = PyMethod_GET_FUNCTION(m_callable); + else + py_func_obj = m_callable; + } + + if (py_func_obj) + { + PyCodeObject* code = (PyCodeObject*)PyFunction_GET_CODE(py_func_obj); if (code) { size_t args = code->co_argcount; @@ -632,15 +641,24 @@ LLDBSwigPython_CallOptionalMember SWIGEXPORT size_t LLDBSwigPython_CalculateNumChildren ( - PyObject *implementor + PyObject *implementor, + uint32_t max ) { - size_t ret_val = UINT32_MAX; + size_t ret_val = 0; bool int_match = false; - static char callee_name[] = "num_children"; + PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor, "num_children"); - PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, NULL); + if (!pfunc) + return ret_val; + + PyObject* py_return = NULL; + auto argc = pfunc.GetNumArguments(); + if (argc.num_args == 1) + py_return = pfunc(); + else if (argc.num_args == 2) + py_return = pfunc(max); if (!py_return) return ret_val; @@ -675,6 +693,9 @@ LLDBSwigPython_CalculateNumChildren PyErr_Clear(); } + if (argc.num_args == 1 && ret_val > max) + ret_val = max; + return ret_val; } diff --git a/lldb/scripts/interface/SBValue.i b/lldb/scripts/interface/SBValue.i index 725c551253bb..ff201d402ee0 100644 --- a/lldb/scripts/interface/SBValue.i +++ b/lldb/scripts/interface/SBValue.i @@ -238,7 +238,7 @@ public: GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic); - + lldb::SBValue CreateChildAtOffset (const char *name, uint32_t offset, lldb::SBType type); @@ -321,6 +321,21 @@ public: uint32_t GetNumChildren (); + %feature("doctstring", " + //------------------------------------------------------------------ + /// Returns the number for children. + /// + /// @param[in] max + /// If max is less the lldb.UINT32_MAX, then the returned value is + /// capped to max. + /// + /// @return + /// An integer value capped to the argument max. + //------------------------------------------------------------------ + ") GetNumChildren; + uint32_t + GetNumChildren (uint32_t max); + void * GetOpaqueType(); diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index d71fc403cdcd..6a558800db71 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -1265,6 +1265,12 @@ SBValue::IsRuntimeSupportValue () uint32_t SBValue::GetNumChildren () +{ + return GetNumChildren (UINT32_MAX); +} + +uint32_t +SBValue::GetNumChildren (uint32_t max) { uint32_t num_children = 0; @@ -1272,16 +1278,15 @@ SBValue::GetNumChildren () ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) - num_children = value_sp->GetNumChildren(); + num_children = value_sp->GetNumChildren(max); if (log) - log->Printf ("SBValue(%p)::GetNumChildren () => %u", - static_cast(value_sp.get()), num_children); + log->Printf ("SBValue(%p)::GetNumChildren (%u) => %u", + static_cast(value_sp.get()), max, num_children); return num_children; } - SBValue SBValue::Dereference () { diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index d3df421da2c3..ddf86277623b 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -149,7 +149,7 @@ LLDBSWIGPythonCallThreadPlan (void *implementor, bool &got_error); extern "C" size_t -LLDBSwigPython_CalculateNumChildren (void *implementor); +LLDBSwigPython_CalculateNumChildren (void *implementor, uint32_t max); extern "C" void * LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx); diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 708526d4469b..ecafd202e4ca 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -770,9 +770,21 @@ ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create) size_t -ValueObject::GetNumChildren () +ValueObject::GetNumChildren (uint32_t max) { UpdateValueIfNeeded(); + + if (max < UINT32_MAX) + { + if (m_children_count_valid) + { + size_t children_count = m_children.GetChildrenCount(); + return children_count <= max ? children_count : max; + } + else + return CalculateNumChildren(max); + } + if (!m_children_count_valid) { SetNumChildren (CalculateNumChildren()); diff --git a/lldb/source/Core/ValueObjectCast.cpp b/lldb/source/Core/ValueObjectCast.cpp index ac7562024ac9..1c5838b820e1 100644 --- a/lldb/source/Core/ValueObjectCast.cpp +++ b/lldb/source/Core/ValueObjectCast.cpp @@ -68,9 +68,10 @@ ValueObjectCast::GetCompilerTypeImpl () } size_t -ValueObjectCast::CalculateNumChildren() +ValueObjectCast::CalculateNumChildren(uint32_t max) { - return GetCompilerType().GetNumChildren (true); + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; } uint64_t diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp index 7e95da6a5e93..8b579a5e42c2 100644 --- a/lldb/source/Core/ValueObjectChild.cpp +++ b/lldb/source/Core/ValueObjectChild.cpp @@ -62,9 +62,10 @@ ValueObjectChild::GetValueType() const } size_t -ValueObjectChild::CalculateNumChildren() +ValueObjectChild::CalculateNumChildren(uint32_t max) { - return GetCompilerType().GetNumChildren (true); + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; } static void diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp index 6154829b240e..a0f1737a861c 100644 --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -270,9 +270,10 @@ ValueObjectConstResult::SetByteSize (size_t size) } size_t -ValueObjectConstResult::CalculateNumChildren() +ValueObjectConstResult::CalculateNumChildren(uint32_t max) { - return GetCompilerType().GetNumChildren (true); + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; } ConstString diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp index 3de12e5a66f1..cec2ca523844 100644 --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -113,13 +113,16 @@ ValueObjectDynamicValue::GetDisplayTypeName() } size_t -ValueObjectDynamicValue::CalculateNumChildren() +ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) { const bool success = UpdateValueIfNeeded(false); if (success && m_dynamic_type_info.HasType()) - return GetCompilerType().GetNumChildren (true); + { + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; + } else - return m_parent->GetNumChildren(); + return m_parent->GetNumChildren(max); } uint64_t diff --git a/lldb/source/Core/ValueObjectMemory.cpp b/lldb/source/Core/ValueObjectMemory.cpp index fa483516d8e8..b989710c95d5 100644 --- a/lldb/source/Core/ValueObjectMemory.cpp +++ b/lldb/source/Core/ValueObjectMemory.cpp @@ -156,12 +156,17 @@ ValueObjectMemory::GetDisplayTypeName() } size_t -ValueObjectMemory::CalculateNumChildren() +ValueObjectMemory::CalculateNumChildren(uint32_t max) { if (m_type_sp) - return m_type_sp->GetNumChildren(true); + { + auto child_count = m_type_sp->GetNumChildren(true); + return child_count <= max ? child_count : max; + } + const bool omit_empty_base_classes = true; - return m_compiler_type.GetNumChildren (omit_empty_base_classes); + auto child_count = m_compiler_type.GetNumChildren (omit_empty_base_classes); + return child_count <= max ? child_count : max; } uint64_t diff --git a/lldb/source/Core/ValueObjectRegister.cpp b/lldb/source/Core/ValueObjectRegister.cpp index 1e8a4156a613..c7845cd03207 100644 --- a/lldb/source/Core/ValueObjectRegister.cpp +++ b/lldb/source/Core/ValueObjectRegister.cpp @@ -67,9 +67,10 @@ ValueObjectRegisterContext::GetQualifiedTypeName() } size_t -ValueObjectRegisterContext::CalculateNumChildren() +ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) { - return m_reg_ctx_sp->GetRegisterSetCount(); + auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount(); + return reg_set_count <= max ? reg_set_count : max; } uint64_t @@ -163,11 +164,14 @@ ValueObjectRegisterSet::GetQualifiedTypeName() } size_t -ValueObjectRegisterSet::CalculateNumChildren() +ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) { const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx); if (reg_set) - return reg_set->num_registers; + { + auto reg_count = reg_set->num_registers; + return reg_count <= max ? reg_count : max; + } return 0; } @@ -338,9 +342,10 @@ ValueObjectRegister::GetTypeName() } size_t -ValueObjectRegister::CalculateNumChildren() +ValueObjectRegister::CalculateNumChildren(uint32_t max) { - return GetCompilerType().GetNumChildren(true); + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; } uint64_t diff --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp index e82862af1df9..0ba0282448b3 100644 --- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -26,7 +26,7 @@ public: {} size_t - CalculateNumChildren() + CalculateNumChildren () { return m_backend.GetNumChildren(); } @@ -36,7 +36,7 @@ public: { return m_backend.GetChildAtIndex(idx, true); } - + size_t GetIndexOfChildWithName (const ConstString &name) { @@ -107,12 +107,16 @@ ValueObjectSynthetic::GetDisplayTypeName() } size_t -ValueObjectSynthetic::CalculateNumChildren() +ValueObjectSynthetic::CalculateNumChildren(uint32_t max) { UpdateValueIfNeeded(); if (m_synthetic_children_count < UINT32_MAX) - return m_synthetic_children_count; - return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren()); + return m_synthetic_children_count <= max ? m_synthetic_children_count : max; + + if (max < UINT32_MAX) + return m_synth_filter_ap->CalculateNumChildren(max); + else + return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren(max)); } lldb::ValueObjectSP diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp index 72107400bfc9..389b7c54243d 100644 --- a/lldb/source/Core/ValueObjectVariable.cpp +++ b/lldb/source/Core/ValueObjectVariable.cpp @@ -91,7 +91,7 @@ ValueObjectVariable::GetQualifiedTypeName() } size_t -ValueObjectVariable::CalculateNumChildren() +ValueObjectVariable::CalculateNumChildren(uint32_t max) { CompilerType type(GetCompilerType()); @@ -99,7 +99,8 @@ ValueObjectVariable::CalculateNumChildren() return 0; const bool omit_empty_base_classes = true; - return type.GetNumChildren(omit_empty_base_classes); + auto child_count = type.GetNumChildren(omit_empty_base_classes); + return child_count <= max ? child_count : max; } uint64_t diff --git a/lldb/source/DataFormatters/TypeSynthetic.cpp b/lldb/source/DataFormatters/TypeSynthetic.cpp index 4098d59c8c70..e49cd99b02ea 100644 --- a/lldb/source/DataFormatters/TypeSynthetic.cpp +++ b/lldb/source/DataFormatters/TypeSynthetic.cpp @@ -200,7 +200,15 @@ ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren () { if (!m_wrapper_sp || m_interpreter == NULL) return 0; - return m_interpreter->CalculateNumChildren(m_wrapper_sp); + return m_interpreter->CalculateNumChildren(m_wrapper_sp, UINT32_MAX); +} + +size_t +ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren (uint32_t max) +{ + if (!m_wrapper_sp || m_interpreter == NULL) + return 0; + return m_interpreter->CalculateNumChildren(m_wrapper_sp, max); } bool diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 32e64f4a8c22..b623626073d2 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -2199,7 +2199,7 @@ ScriptInterpreterPython::WatchpointCallbackFunction } size_t -ScriptInterpreterPython::CalculateNumChildren(const StructuredData::ObjectSP &implementor_sp) +ScriptInterpreterPython::CalculateNumChildren(const StructuredData::ObjectSP &implementor_sp, uint32_t max) { if (!implementor_sp) return 0; @@ -2217,7 +2217,7 @@ ScriptInterpreterPython::CalculateNumChildren(const StructuredData::ObjectSP &im { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = g_swig_calc_children (implementor); + ret_val = g_swig_calc_children (implementor, max); } return ret_val; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h index 23576658bd9c..cdba5829dc0a 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h @@ -73,7 +73,7 @@ public: const char *session_dictionary_name, const lldb::ProcessSP& process_sp); - typedef size_t (*SWIGPythonCalculateNumChildren) (void *implementor); + typedef size_t (*SWIGPythonCalculateNumChildren) (void *implementor, uint32_t max); typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx); typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name); typedef void* (*SWIGPythonCastPyObjectToSBValue) (void* data); @@ -200,7 +200,7 @@ public: StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Error &error) override; - size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor) override; + size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, uint32_t max) override; lldb::ValueObjectSP GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) override; diff --git a/lldb/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py b/lldb/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py index cdff8e4b7455..65f573322216 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py +++ b/lldb/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py @@ -66,6 +66,7 @@ class DataFormatterSynthValueTestCase(TestBase): # now set up the synth self.runCmd("script from myIntSynthProvider import *") self.runCmd("type synth add -l myIntSynthProvider myInt") + self.runCmd("type synth add -l myArraySynthProvider myArray") if self.TraceOn(): print "x_val = %s; y_val = %s; z_val = %s" % (x_val(),y_val(),z_val()) @@ -85,6 +86,12 @@ class DataFormatterSynthValueTestCase(TestBase): hi = self.frame().FindVariable("hi") self.assertEqual(hi.GetSummary(), "42") + ma = self.frame().FindVariable("ma") + self.assertTrue(ma.IsValid()) + self.assertEqual(ma.GetNumChildren(15), 15) + self.assertEqual(ma.GetNumChildren(16), 16) + self.assertEqual(ma.GetNumChildren(17), 16) + if __name__ == '__main__': import atexit lldb.SBDebugger.Initialize() diff --git a/lldb/test/functionalities/data-formatter/data-formatter-synthval/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-synthval/main.cpp index a77d438fc0ca..accbf0a5a578 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-synthval/main.cpp +++ b/lldb/test/functionalities/data-formatter/data-formatter-synthval/main.cpp @@ -5,6 +5,11 @@ class myInt { int val() { return theValue; } }; +class myArray { +public: + int array[16]; +}; + class hasAnInt { public: myInt theInt; @@ -18,5 +23,7 @@ int main() { myInt y{4}; myInt z {x+y}; hasAnInt hi; + myArray ma; + return z.val(); // break here } diff --git a/lldb/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py b/lldb/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py index c716836a6737..c8517a442932 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py +++ b/lldb/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py @@ -15,3 +15,22 @@ class myIntSynthProvider(object): def get_value(self): return self.val + +class myArraySynthProvider(object): + def __init__(self, valobj, dict): + self.valobj = valobj + self.array = self.valobj.GetChildMemberWithName("array") + + def num_children(self, max_count): + if 16 < max_count: + return 16 + return max_count + + def get_child_at_index(self, index): + return None # Keep it simple when this is not tested here. + + def get_child_index(self, name): + return None # Keep it simple when this is not tested here. + + def has_children(self): + return True